Skip to content

Commit

Permalink
Fix bug with updating an existing resource.
Browse files Browse the repository at this point in the history
Use Long as database identifier instead of UUID (but still store the UUID)
  • Loading branch information
arucard21 committed Mar 19, 2020
1 parent 0f8409f commit df1eacb
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 64 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
* @param <E> is the entity used to persist data (which contains a UUID field)
*/
@Named
public interface SpringDataRepository<E> extends PagingAndSortingRepository<E, UUID>{
public interface SpringDataRepository<E> extends PagingAndSortingRepository<E, Long>{
Optional<E> findByUuid(UUID uuid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,78 +33,92 @@
import simplyrestful.springdata.repository.SpringDataRepository;

public class SpringDataWebResource<T extends SpringDataHALResource> extends DefaultWebResource<T> {
private static final String ERROR_RESOURCE_NO_IDENTIFIER = "Resource contains no unique identifier at all, neither a UUID nor a self link.";
private SpringDataRepository<T> 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<T> repo;

public SpringDataWebResource(SpringDataRepository<T> 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<T> entity = repo.findByUuid(resourceUUID);
if (entity.isPresent()) {
T retrievedEntity = entity.get();
ensureSelfLinkAndUUIDPresent(retrievedEntity);
return retrievedEntity;
public SpringDataWebResource(SpringDataRepository<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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);
}
}
}
}

0 comments on commit df1eacb

Please sign in to comment.