DATAJPA-1576 - JpaMetamodelEntityInformation uses getters to access ids from proxies.

Note that it still uses field access for non proxy entities.

Signed-off-by: Jens Schauder <jschauder@pivotal.io>
Original pull request: #421.
This commit is contained in:
Jens Schauder
2019-07-23 10:35:02 +02:00
committed by Mark Paluch
parent d2b18f9d51
commit 97c05c5db2
3 changed files with 41 additions and 0 deletions

View File

@@ -35,6 +35,7 @@ import javax.persistence.metamodel.Type.PersistenceType;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.jpa.provider.PersistenceProvider;
import org.springframework.data.jpa.util.JpaMetamodel;
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;
import org.springframework.data.util.ProxyUtils;
@@ -147,6 +148,14 @@ public class JpaMetamodelEntityInformation<T, ID> extends JpaEntityInformationSu
@SuppressWarnings("unchecked")
public ID getId(T entity) {
// check if this is a proxy. If so use Proxy mechanics to access the id.
PersistenceProvider persistenceProvider = PersistenceProvider.fromMetamodel(metamodel);
if (persistenceProvider.shouldUseAccessorFor(entity)) {
return (ID) persistenceProvider.getIdentifierFrom(entity);
}
// if not a proxy use Spring mechanics to access the id.
BeanWrapper entityWrapper = new DirectFieldAccessFallbackBeanWrapper(entity);
if (idMetadata.hasSimpleId()) {

View File

@@ -301,6 +301,22 @@ public class JpaMetamodelEntityInformationIntegrationTests {
assertThat(pk.getSecond()).isEqualTo(42L);
}
@Test // DATAJPA-1576
@Ignore
public void prefersPrivateGetterOverFieldAccess() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(getMetadadataPersitenceUnitName());
EntityManager em = emf.createEntityManager();
JpaEntityInformation<EntityWithPrivateIdGetter, ?> information = getEntityInformation(EntityWithPrivateIdGetter.class, em);
EntityWithPrivateIdGetter entity = new EntityWithPrivateIdGetter();
Object id = information.getId(entity);
assertThat(id).isEqualTo(42L);
}
protected String getMetadadataPersitenceUnitName() {
return "metadata";
}
@@ -358,4 +374,19 @@ public class JpaMetamodelEntityInformationIntegrationTests {
Long id;
EntityWithIdClassPK reference;
}
@Entity
public static class EntityWithPrivateIdGetter implements Serializable{
private long id = 0;
@Id
private long getId() {
return 42;
}
public void setId(long id) {
this.id = id;
}
}
}

View File

@@ -100,6 +100,7 @@
<class>org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$Sample</class>
<class>org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$EntityWithNestedIdClass</class>
<class>org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$EntityWithIdClass</class>
<class>org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$EntityWithPrivateIdGetter</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />