diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java index f526e23b8..120207b88 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java @@ -321,12 +321,13 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem List ifNoneMatch = headers.getIfNoneMatch(); ETag eTag = ifNoneMatch.isEmpty() ? ETag.NO_ETAG : ETag.from(ifNoneMatch.get(0)); PersistentEntity entity = resourceInformation.getPersistentEntity(); + HttpHeaders responseHeaders = prepareHeaders(entity, domainObj); if (eTag.matches(entity, domainObj)) { - return new ResponseEntity>(prepareHeaders(entity, domainObj), HttpStatus.NOT_MODIFIED); + return new ResponseEntity>(responseHeaders, HttpStatus.NOT_MODIFIED); } - // Check last modification for If-Modfied-Since + // Check last modification for If-Modified-Since if (headers.getIfModifiedSince() != -1) { @@ -334,12 +335,12 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem long current = wrapper.getLastModifiedDate().getTimeInMillis() / 1000 * 1000; if (current <= headers.getIfModifiedSince()) { - return new ResponseEntity>(prepareHeaders(entity, domainObj), HttpStatus.NOT_MODIFIED); + return new ResponseEntity>(responseHeaders, HttpStatus.NOT_MODIFIED); } } PersistentEntityResource resource = assembler.toFullResource(domainObj); - return new ResponseEntity>(resource, prepareHeaders(resource), HttpStatus.OK); + return new ResponseEntity>(resource, responseHeaders, HttpStatus.OK); } /** diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryEntityControllerIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryEntityControllerIntegrationTests.java index 83d351ee5..48a3b2c3d 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryEntityControllerIntegrationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryEntityControllerIntegrationTests.java @@ -23,8 +23,10 @@ import static org.springframework.http.HttpMethod.*; import java.util.List; import org.junit.Test; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mapping.context.PersistentEntities; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.jpa.Address; import org.springframework.data.rest.webmvc.jpa.AddressRepository; @@ -33,12 +35,14 @@ import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig; import org.springframework.data.rest.webmvc.jpa.Order; import org.springframework.data.rest.webmvc.jpa.Person; import org.springframework.data.rest.webmvc.support.ETag; +import org.springframework.hateoas.Resource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.HttpRequestMethodNotSupportedException; /** @@ -244,4 +248,29 @@ public class RepositoryEntityControllerIntegrationTests extends AbstractControll is(false)); assertThat(controller.postCollectionResource(request, persistentEntityResource, assembler, "").hasBody(), is(false)); } + + /** + * @see DATAREST-581 + */ + @Test + public void createsEtagForProjectedEntityCorrectly() throws Exception { + + Address address = repository.save(new Address()); + + PersistentEntityResourceAssembler assembler = Mockito.mock(PersistentEntityResourceAssembler.class); + AddressProjection addressProjection = new SpelAwareProxyProjectionFactory() + .createProjection(AddressProjection.class); + + PersistentEntityResource resource = PersistentEntityResource + .build(addressProjection, entities.getPersistentEntity(Address.class)).build(); + + Mockito.when(assembler.toFullResource(Mockito.any(Object.class))).thenReturn(resource); + + ResponseEntity> entity = controller.getItemResource(getResourceInformation(Address.class), address.id, + assembler, new LinkedMultiValueMap()); + + assertThat(entity.getHeaders().getETag(), is(notNullValue())); + } + + interface AddressProjection {} } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Address.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Address.java index b4ac3fb21..1ae854732 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Address.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Address.java @@ -18,6 +18,7 @@ package org.springframework.data.rest.webmvc.jpa; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.Version; /** * @author Oliver Gierke @@ -26,4 +27,5 @@ import javax.persistence.Id; public class Address { public @Id @GeneratedValue Long id; + public @Version Long version; }