diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformation.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformation.java index 3fb649031..5f71a2d4a 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformation.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformation.java @@ -46,6 +46,7 @@ import org.springframework.util.ReflectionUtils; public class JpaMetamodelEntityInformation extends JpaEntityInformationSupport { private final IdMetadata idMetadata; + private final SingularAttribute versionAttribute; /** * Creates a new {@link JpaMetamodelEntityInformation} for the given domain class and {@link Metamodel}. @@ -69,6 +70,26 @@ public class JpaMetamodelEntityInformation extends J } this.idMetadata = new IdMetadata((IdentifiableType) type); + this.versionAttribute = findVersionAttribute(type); + } + + /** + * Returns the version attribute of the given {@link ManagedType} or {@literal null} if none available. + * + * @param type must not be {@literal null}. + * @return + */ + private static SingularAttribute findVersionAttribute(ManagedType type) { + + Set> attributes = type.getSingularAttributes(); + + for (SingularAttribute attribute : attributes) { + if (attribute.isVersion()) { + return attribute; + } + } + + return null; } /* @@ -153,6 +174,20 @@ public class JpaMetamodelEntityInformation extends J return new DirectFieldAccessFallbackBeanWrapper(id).getPropertyValue(idAttribute); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.core.support.AbstractEntityInformation#isNew(java.lang.Object) + */ + @Override + public boolean isNew(T entity) { + + if (versionAttribute == null) { + return super.isNew(entity); + } + + return new DirectFieldAccessFallbackBeanWrapper(entity).getPropertyValue(versionAttribute.getName()) == null; + } + /** * Simple value object to encapsulate id specific metadata. * diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/VersionedUser.java b/src/test/java/org/springframework/data/jpa/domain/sample/VersionedUser.java new file mode 100644 index 000000000..6a301001c --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/domain/sample/VersionedUser.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.domain.sample; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Version; + +/** + * @author Oliver Gierke + */ +@Entity +public class VersionedUser { + + @Id + @GeneratedValue + private Long id; + + @Version + private Long version; + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the version + */ + public Long getVersion() { + return version; + } + + /** + * @param version the version to set + */ + public void setVersion(Long version) { + this.version = version; + } +} diff --git a/src/test/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformationIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformationIntegrationTests.java index d3b11a24c..dbf831b1e 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformationIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 the original author or authors. + * Copyright 2011-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.data.jpa.domain.sample.SampleWithIdClass; import org.springframework.data.jpa.domain.sample.SampleWithIdClassPK; import org.springframework.data.jpa.domain.sample.User; +import org.springframework.data.jpa.domain.sample.VersionedUser; import org.springframework.data.repository.core.EntityInformation; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -92,4 +93,23 @@ public class JpaMetamodelEntityInformationIntegrationTests { assertThat(id, is(instanceOf(SampleWithIdClassPK.class))); assertThat(id, is((Object) new SampleWithIdClassPK(2L, 4L))); } + + /** + * @see DATAJPA-119 + */ + @Test + public void favoursVersionAnnotationIfPresent() { + + EntityInformation information = new JpaMetamodelEntityInformation( + VersionedUser.class, em.getMetamodel()); + + VersionedUser entity = new VersionedUser(); + assertThat(information.isNew(entity), is(true)); + entity.setId(1L); + assertThat(information.isNew(entity), is(true)); + entity.setVersion(1L); + assertThat(information.isNew(entity), is(false)); + entity.setId(null); + assertThat(information.isNew(entity), is(false)); + } } diff --git a/src/test/resources/META-INF/persistence.xml b/src/test/resources/META-INF/persistence.xml index fda60fa7c..c503b7a85 100644 --- a/src/test/resources/META-INF/persistence.xml +++ b/src/test/resources/META-INF/persistence.xml @@ -14,6 +14,7 @@ org.springframework.data.jpa.domain.sample.SampleEntity org.springframework.data.jpa.domain.sample.SampleEntityPK org.springframework.data.jpa.domain.sample.SampleWithIdClass + org.springframework.data.jpa.domain.sample.VersionedUser true