From df1eacbf9547296f5ceccf414c179e0f67a37a5a Mon Sep 17 00:00:00 2001 From: Riaas Mokiem Date: Thu, 19 Mar 2020 16:04:52 +0100 Subject: [PATCH] Fix bug with updating an existing resource. Use Long as database identifier instead of UUID (but still store the UUID) --- build.gradle | 2 +- .../repository/SpringDataRepository.java | 2 +- .../resources/SpringDataHALResource.java | 20 +++ .../resources/SpringDataWebResource.java | 138 ++++++++++-------- 4 files changed, 98 insertions(+), 64 deletions(-) diff --git a/build.gradle b/build.gradle index d0b488a6..6e5c69dd 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ allprojects{ } group = 'com.github.arucard21.simplyrestful' - version = '0.11.3' + version = '0.11.4' sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 diff --git a/persist-springdata/src/main/java/simplyrestful/springdata/repository/SpringDataRepository.java b/persist-springdata/src/main/java/simplyrestful/springdata/repository/SpringDataRepository.java index 17da9eec..7742a3a2 100644 --- a/persist-springdata/src/main/java/simplyrestful/springdata/repository/SpringDataRepository.java +++ b/persist-springdata/src/main/java/simplyrestful/springdata/repository/SpringDataRepository.java @@ -15,6 +15,6 @@ * @param is the entity used to persist data (which contains a UUID field) */ @Named -public interface SpringDataRepository extends PagingAndSortingRepository{ +public interface SpringDataRepository extends PagingAndSortingRepository{ Optional findByUuid(UUID uuid); } diff --git a/persist-springdata/src/main/java/simplyrestful/springdata/resources/SpringDataHALResource.java b/persist-springdata/src/main/java/simplyrestful/springdata/resources/SpringDataHALResource.java index 7056b31c..b0b29f23 100644 --- a/persist-springdata/src/main/java/simplyrestful/springdata/resources/SpringDataHALResource.java +++ b/persist-springdata/src/main/java/simplyrestful/springdata/resources/SpringDataHALResource.java @@ -2,19 +2,39 @@ import java.util.UUID; +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; import javax.persistence.MappedSuperclass; import javax.validation.constraints.NotNull; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import simplyrestful.api.framework.resources.HALResource; +@JsonIgnoreProperties(ignoreUnknown = true) @MappedSuperclass public abstract class SpringDataHALResource extends HALResource{ + @Id + @Column(name = "id") + @GeneratedValue(strategy=GenerationType.IDENTITY) + @JsonIgnore + private long id; + @JsonIgnore @NotNull UUID uuid; + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + public UUID getUUID() { return uuid; } diff --git a/persist-springdata/src/main/java/simplyrestful/springdata/resources/SpringDataWebResource.java b/persist-springdata/src/main/java/simplyrestful/springdata/resources/SpringDataWebResource.java index a1ae97ae..78b5b8bd 100644 --- a/persist-springdata/src/main/java/simplyrestful/springdata/resources/SpringDataWebResource.java +++ b/persist-springdata/src/main/java/simplyrestful/springdata/resources/SpringDataWebResource.java @@ -33,78 +33,92 @@ import simplyrestful.springdata.repository.SpringDataRepository; public class SpringDataWebResource extends DefaultWebResource { - private static final String ERROR_RESOURCE_NO_IDENTIFIER = "Resource contains no unique identifier at all, neither a UUID nor a self link."; - private SpringDataRepository repo; + private static final String ERROR_UPDATE_RESOURCE_DOES_NOT_EXIST = "The provided resources does not exist so it can not be updated"; + private static final String ERROR_CREATE_RESOURCE_ALREADY_EXISTS = "The provided resources already exists so it can not be created"; + private static final String ERROR_RESOURCE_NO_IDENTIFIER = "Resource contains no unique identifier at all, neither a UUID nor a self link."; + private SpringDataRepository repo; - public SpringDataWebResource(SpringDataRepository repo) { - this.repo = repo; - } - - @Override - public T create(T resource, UUID resourceUUID) { - ensureSelfLinkAndUUIDPresent(resource); - T entity = repo.save(resource); - ensureSelfLinkAndUUIDPresent(entity); - return entity; - } - - @Override - public T read(UUID resourceUUID) { - Optional entity = repo.findByUuid(resourceUUID); - if (entity.isPresent()) { - T retrievedEntity = entity.get(); - ensureSelfLinkAndUUIDPresent(retrievedEntity); - return retrievedEntity; + public SpringDataWebResource(SpringDataRepository repo) { + this.repo = repo; } - return null; - } - @Override - public T update(T resource, UUID resourceUUID) { - ensureSelfLinkAndUUIDPresent(resource); - T entity = repo.save(resource); - ensureSelfLinkAndUUIDPresent(entity); - return entity; - } + @Override + public T create(T resource, UUID resourceUUID) { + ensureSelfLinkAndUUIDPresent(resource); + Optional entity = repo.findByUuid(resourceUUID); + if (entity.isPresent()) { + throw new IllegalArgumentException(ERROR_CREATE_RESOURCE_ALREADY_EXISTS); + } + T persistedEntity = repo.save(resource); + ensureSelfLinkAndUUIDPresent(persistedEntity); + return persistedEntity; + } - @Override - public T delete(UUID resourceUUID) { - T previousValue = read(resourceUUID); - if (previousValue == null) { + @Override + public T read(UUID resourceUUID) { + Optional entity = repo.findByUuid(resourceUUID); + if (entity.isPresent()) { + T retrievedEntity = entity.get(); + ensureSelfLinkAndUUIDPresent(retrievedEntity); + return retrievedEntity; + } return null; } - repo.delete(previousValue); - ensureSelfLinkAndUUIDPresent(previousValue); - return previousValue; - } - @Override - public List list(long pageNumber, long pageSize) { - int pageZeroIndexed = Math.toIntExact(pageNumber) - 1; - int integerPageSize = (pageSize > Integer.valueOf(Integer.MAX_VALUE).longValue()) ? Integer.MAX_VALUE : Math.toIntExact(pageSize); - List retrievedPage = repo.findAll(PageRequest.of(pageZeroIndexed, integerPageSize)).getContent(); - retrievedPage.forEach(resource -> ensureSelfLinkAndUUIDPresent(resource)); - return retrievedPage; - } + @Override + public T update(T resource, UUID resourceUUID) { + ensureSelfLinkAndUUIDPresent(resource); + Optional entity = repo.findByUuid(resourceUUID); + if (entity.isPresent()) { + T retrievedEntity = entity.get(); + resource.setId(retrievedEntity.getId()); + resource.setUUID(resourceUUID); + T persistedEntity = repo.save(resource); + ensureSelfLinkAndUUIDPresent(persistedEntity); + return persistedEntity; + } + throw new IllegalArgumentException(ERROR_UPDATE_RESOURCE_DOES_NOT_EXIST); + } - protected SpringDataRepository getRepo() { - return repo; - } + @Override + public T delete(UUID resourceUUID) { + T previousValue = read(resourceUUID); + if (previousValue == null) { + return null; + } + repo.delete(previousValue); + ensureSelfLinkAndUUIDPresent(previousValue); + return previousValue; + } - private void ensureSelfLinkAndUUIDPresent(T persistedResource) { - if (persistedResource.getSelf() == null && persistedResource.getUUID() == null) { - throw new IllegalStateException(ERROR_RESOURCE_NO_IDENTIFIER); + @Override + public List list(long pageNumber, long pageSize) { + int pageZeroIndexed = Math.toIntExact(pageNumber) - 1; + int integerPageSize = (pageSize > Integer.valueOf(Integer.MAX_VALUE).longValue()) ? Integer.MAX_VALUE + : Math.toIntExact(pageSize); + List retrievedPage = repo.findAll(PageRequest.of(pageZeroIndexed, integerPageSize)).getContent(); + retrievedPage.forEach(resource -> ensureSelfLinkAndUUIDPresent(resource)); + return retrievedPage; } - if (persistedResource.getSelf() == null) { - persistedResource.setSelf(new HALLink.Builder(UriBuilder.fromUri(getAbsoluteWebResourceURI()) - .path(persistedResource.getUUID().toString()).build()) - .type(AdditionalMediaTypes.APPLICATION_HAL_JSON).profile(persistedResource.getProfile()) - .build()); + + protected SpringDataRepository getRepo() { + return repo; } - if (persistedResource.getUUID() == null) { - UUID id = UUID.fromString(getAbsoluteWebResourceURI() - .relativize(URI.create(persistedResource.getSelf().getHref())).getPath()); - persistedResource.setUUID(id); + + private void ensureSelfLinkAndUUIDPresent(T persistedResource) { + if (persistedResource.getSelf() == null && persistedResource.getUUID() == null) { + throw new IllegalStateException(ERROR_RESOURCE_NO_IDENTIFIER); + } + if (persistedResource.getSelf() == null) { + persistedResource.setSelf(new HALLink.Builder(UriBuilder.fromUri(getAbsoluteWebResourceURI()) + .path(persistedResource.getUUID().toString()).build()) + .type(AdditionalMediaTypes.APPLICATION_HAL_JSON).profile(persistedResource.getProfile()) + .build()); + } + if (persistedResource.getUUID() == null) { + UUID id = UUID.fromString(getAbsoluteWebResourceURI() + .relativize(URI.create(persistedResource.getSelf().getHref())).getPath()); + persistedResource.setUUID(id); + } } - } }