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 78a83b79c..7723e64a8 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 @@ -39,6 +39,7 @@ import org.springframework.data.jpa.util.JpaMetamodel; import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * Implementation of {@link org.springframework.data.repository.core.EntityInformation} that uses JPA {@link Metamodel} @@ -343,8 +344,8 @@ public class JpaMetamodelEntityInformation extends JpaEntityInformationSu // Derive the identifier from the nested entity that is part of the composite key. @SuppressWarnings("rawtypes") - JpaMetamodelEntityInformation nestedEntityInformation = new JpaMetamodelEntityInformation(value.getClass(), - this.metamodel); + JpaMetamodelEntityInformation nestedEntityInformation = new JpaMetamodelEntityInformation( + ClassUtils.getUserClass(value), this.metamodel); if (!nestedEntityInformation.getJavaType().isAnnotationPresent(IdClass.class)) { @@ -413,7 +414,7 @@ public class JpaMetamodelEntityInformation extends JpaEntityInformationSu } try { - ManagedType managedType = this.metamodel.managedType(value.getClass()); + ManagedType managedType = this.metamodel.managedType(ClassUtils.getUserClass(value)); return managedType != null && managedType.getPersistenceType() == PersistenceType.ENTITY; } catch (IllegalArgumentException iae) { // no mapped type diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/SampleWithIdClassIncludingEntity.java b/src/test/java/org/springframework/data/jpa/domain/sample/SampleWithIdClassIncludingEntity.java new file mode 100644 index 000000000..c50f4b24d --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/domain/sample/SampleWithIdClassIncludingEntity.java @@ -0,0 +1,45 @@ +package org.springframework.data.jpa.domain.sample; + +import lombok.Data; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.IdClass; +import javax.persistence.ManyToOne; + +/** + * Sample class for integration testing + * {@link org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation}. + * + * @author Jens Schauder + */ +@Entity +@IdClass(SampleWithIdClassIncludingEntity.SampleWithIdClassPK.class) +@Data +public class SampleWithIdClassIncludingEntity { + + @Id Long first; + @ManyToOne @Id OtherEntity second; + + @Data + @SuppressWarnings("serial") + public static class SampleWithIdClassPK implements Serializable { + + Long first; + Long second; + } + + @Entity + @Data + public static class OtherEntity { + @Id Long otherId; + } + + /** + * This class emulates a proxy at is returned from Hibernate. + */ + public static class OtherEntity$$PsudoProxy extends OtherEntity {} + +} diff --git a/src/test/java/org/springframework/data/jpa/repository/support/EclipseLinkJpaMetamodelEntityInformationIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/support/EclipseLinkJpaMetamodelEntityInformationIntegrationTests.java index 1892f6c3d..4e5dc0f2d 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/EclipseLinkJpaMetamodelEntityInformationIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/EclipseLinkJpaMetamodelEntityInformationIntegrationTests.java @@ -71,13 +71,28 @@ public class EclipseLinkJpaMetamodelEntityInformationIntegrationTests } /** - * Ignored due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=531528 EclipseLink doesn't support - * {@link javax.persistence.IdClass} referencing inner classes. + * This test fails due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=531528 IdentifiableType.hasSingleIdAttribute() + * returns true when IdClass references an inner class. This bug is supposedly fixed, but the test still fails. */ @Ignore @Test @Override - public void correctlyDeterminesIdValueForNestedIdClassesWithNonPrimitiveNonManagedType() {} + public void correctlyDeterminesIdValueForNestedIdClassesWithNonPrimitiveNonManagedType() { + super.correctlyDeterminesIdValueForNestedIdClassesWithNonPrimitiveNonManagedType(); + } + + /** + * This test fails due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=531528 IdentifiableType.hasSingleIdAttribute() + * returns true when IdClass references an inner class. This bug is supposedly fixed, but the test still fails. + */ + @Ignore + @Test + @Override + public void proxiedIdClassElement() { + super.proxiedIdClassElement(); + } + + @Override protected String getMetadadataPersitenceUnitName() { 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 db8a6fda1..8d41390ff 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 @@ -281,6 +281,28 @@ public class JpaMetamodelEntityInformationIntegrationTests { assertThat(id, is(notNullValue())); } + @Test // DATAJPA-1416 + public void proxiedIdClassElement() { + + JpaEntityInformation information = getEntityInformation( + SampleWithIdClassIncludingEntity.class, em); + + SampleWithIdClassIncludingEntity entity = new SampleWithIdClassIncludingEntity(); + entity.setFirst(23L); + SampleWithIdClassIncludingEntity.OtherEntity$$PsudoProxy inner = new SampleWithIdClassIncludingEntity.OtherEntity$$PsudoProxy(); + inner.setOtherId(42L); + entity.setSecond(inner); + + Object id = information.getId(entity); + + assertTrue(id instanceof SampleWithIdClassIncludingEntity.SampleWithIdClassPK); + + SampleWithIdClassIncludingEntity.SampleWithIdClassPK pk = (SampleWithIdClassIncludingEntity.SampleWithIdClassPK) id; + + assertThat(pk.getFirst(), equalTo(23L)); + assertThat(pk.getSecond(), equalTo(42L)); + } + protected String getMetadadataPersitenceUnitName() { return "metadata"; } diff --git a/src/test/resources/META-INF/persistence.xml b/src/test/resources/META-INF/persistence.xml index c65bcfdcb..ced3e4421 100644 --- a/src/test/resources/META-INF/persistence.xml +++ b/src/test/resources/META-INF/persistence.xml @@ -42,6 +42,8 @@ org.springframework.data.jpa.domain.sample.User org.springframework.data.jpa.domain.sample.VersionedUser org.springframework.data.jpa.domain.sample.Dummy + org.springframework.data.jpa.domain.sample.SampleWithIdClassIncludingEntity + org.springframework.data.jpa.domain.sample.SampleWithIdClassIncludingEntity$OtherEntity true