Skip to content

Commit

Permalink
HHH-11838 - Id retrieving from proxy with FK leads to query execution
Browse files Browse the repository at this point in the history
  • Loading branch information
Igor Dmitriev authored and vladmihalcea committed Sep 21, 2017
1 parent af08088 commit f8b78bc
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,24 @@ private static void verifyNoGetVariantExists(
}
}

public static Method getterMethodOrNull(Class containerJavaType, String propertyName) {
try {
return findGetterMethod( containerJavaType, propertyName );
}
catch (PropertyNotFoundException e) {
return null;
}
}

public static Method setterMethodOrNull(Class containerJavaType, String propertyName, Class propertyJavaType) {
try {
return findSetterMethod( containerJavaType, propertyName, propertyJavaType );
}
catch (PropertyNotFoundException e) {
return null;
}
}

public static Method findSetterMethod(Class containerClass, String propertyName, Class propertyType) {
Class checkClass = containerClass;
Method setter = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import org.hibernate.property.access.spi.SetterFieldImpl;
import org.hibernate.property.access.spi.SetterMethodImpl;

import static org.hibernate.internal.util.ReflectHelper.getterMethodOrNull;
import static org.hibernate.internal.util.ReflectHelper.setterMethodOrNull;

/**
* A PropertyAccess based on mix of getter/setter method and/or field.
*
Expand Down Expand Up @@ -85,24 +88,6 @@ protected static Field fieldOrNull(Class containerJavaType, String propertyName)
}
}

protected static Method getterMethodOrNull(Class containerJavaType, String propertyName) {
try {
return ReflectHelper.findGetterMethod( containerJavaType, propertyName );
}
catch (PropertyNotFoundException e) {
return null;
}
}

protected static Method setterMethodOrNull(Class containerJavaType, String propertyName, Class propertyJavaType) {
try {
return ReflectHelper.findSetterMethod( containerJavaType, propertyName, propertyJavaType );
}
catch (PropertyNotFoundException e) {
return null;
}
}

protected static AccessType getAccessType(Class<?> containerJavaType, String propertyName) {
Field field = fieldOrNull( containerJavaType, propertyName );
AccessType fieldAccessType = getAccessTypeOrNull( field );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Map;

import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.property.access.internal.AbstractFieldSerialForm;

/**
Expand All @@ -26,11 +27,13 @@ public class GetterFieldImpl implements Getter {
private final Class containerClass;
private final String propertyName;
private final Field field;
private final Method getterMethod;

public GetterFieldImpl(Class containerClass, String propertyName, Field field) {
this.containerClass = containerClass;
this.propertyName = propertyName;
this.field = field;
this.getterMethod = ReflectHelper.getterMethodOrNull( containerClass, propertyName);
}

@Override
Expand Down Expand Up @@ -98,12 +101,12 @@ public Member getMember() {

@Override
public String getMethodName() {
return null;
return getterMethod != null ? getterMethod.getName() : null;
}

@Override
public Method getMethod() {
return null;
return getterMethod;
}

private Object writeReplace() throws ObjectStreamException {
Expand All @@ -123,5 +126,6 @@ private SerialForm(Class containerClass, String propertyName, Field field) {
private Object readResolve() {
return new GetterFieldImpl( containerClass, propertyName, resolveField() );
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import org.hibernate.PropertyAccessException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.property.access.internal.AbstractFieldSerialForm;

/**
Expand All @@ -25,11 +26,13 @@ public class SetterFieldImpl implements Setter {
private final Class containerClass;
private final String propertyName;
private final Field field;
private final Method setterMethod;

public SetterFieldImpl(Class containerClass, String propertyName, Field field) {
this.containerClass = containerClass;
this.propertyName = propertyName;
this.field = field;
this.setterMethod = ReflectHelper.setterMethodOrNull( containerClass, propertyName, field.getType() );
}

@Override
Expand Down Expand Up @@ -72,12 +75,12 @@ public void set(Object target, Object value, SessionFactoryImplementor factory)

@Override
public String getMethodName() {
return null;
return setterMethod != null ? setterMethod.getName() : null;
}

@Override
public Method getMethod() {
return null;
return setterMethod;
}

private Object writeReplace() throws ObjectStreamException {
Expand All @@ -88,6 +91,7 @@ private static class SerialForm extends AbstractFieldSerialForm implements Seria
private final Class containerClass;
private final String propertyName;


private SerialForm(Class containerClass, String propertyName, Field field) {
super( field );
this.containerClass = containerClass;
Expand All @@ -97,5 +101,6 @@ private SerialForm(Class containerClass, String propertyName, Field field) {
private Object readResolve() {
return new SetterFieldImpl( containerClass, propertyName, resolveField() );
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
*/
public class GetLoadTest extends BaseEntityManagerFunctionalTestCase {
@Test
public void testGetLoad() {
public void testGet() {
clearCounts();

EntityManager em = getOrCreateEntityManager();
Expand Down Expand Up @@ -62,22 +62,42 @@ public void testGetLoad() {
em = getOrCreateEntityManager();
em.getTransaction().begin();
s = ( Session ) em.getDelegate();
emp = ( Employer ) s.load( Employer.class, emp.getId() );
emp.getId();
assertFalse( Hibernate.isInitialized( emp ) );
node = ( Node ) s.load( Node.class, node.getName() );
assertEquals( node.getName(), "foo" );
assertFalse( Hibernate.isInitialized( node ) );
emp = ( Employer ) s.get( Employer.class.getName(), emp.getId() );
assertTrue( Hibernate.isInitialized( emp ) );
node = ( Node ) s.get( Node.class.getName(), node.getName() );
assertTrue( Hibernate.isInitialized( node ) );
em.getTransaction().commit();
em.close();

assertFetchCount( 0 );
}

@Test
public void testLoad() {
clearCounts();

EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
Session s = ( Session ) em.getDelegate();

Employer emp = new Employer();
s.persist( emp );
Node node = new Node( "foo" );
Node parent = new Node( "bar" );
parent.addChild( node );
s.persist( parent );
em.getTransaction().commit();
em.close();

em = getOrCreateEntityManager();
em.getTransaction().begin();
s = ( Session ) em.getDelegate();
emp = ( Employer ) s.get( Employer.class.getName(), emp.getId() );
assertTrue( Hibernate.isInitialized( emp ) );
node = ( Node ) s.get( Node.class.getName(), node.getName() );
assertTrue( Hibernate.isInitialized( node ) );
emp = ( Employer ) s.load( Employer.class, emp.getId() );
emp.getId();
assertFalse( Hibernate.isInitialized( emp ) );
node = ( Node ) s.load( Node.class, node.getName() );
assertEquals( node.getName(), "foo" );
assertFalse( Hibernate.isInitialized( node ) );
em.getTransaction().commit();
em.close();

Expand Down Expand Up @@ -123,6 +143,34 @@ public void testNonEntity() {
}
}

@Test
@TestForIssue( jiraKey = "HHH-11838")
public void testLoadGetId() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
Session s = ( Session ) em.getDelegate();
Workload workload = new Workload();
s.persist(workload);
em.getTransaction().commit();
em.close();

em = getOrCreateEntityManager();
em.getTransaction().begin();
s = ( Session ) em.getDelegate();

Workload proxy = s.load(Workload.class, workload.id);
proxy.getId();

assertFalse( Hibernate.isInitialized( proxy ) );

proxy.getName();

assertTrue( Hibernate.isInitialized( proxy ) );

em.getTransaction().commit();
em.close();
}

@Override
@SuppressWarnings( {"unchecked"})
protected void addConfigOptions(Map options) {
Expand All @@ -137,5 +185,10 @@ protected String[] getMappings() {
"org/hibernate/jpa/test/ops/Employer.hbm.xml"
};
}

@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { Workload.class };
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ public class Workload {
public String name;
@Column(name="load_")
public Integer load;

public Integer getId() {
return id;
}

public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public void testDirectIdPropertyAccess() throws Exception {
o = ( Order ) s.load( Order.class, 1 );
assertFalse( Hibernate.isInitialized( o ) );
o.getOrderNumber();
// If you mapped with field access, any method call initializes the proxy
// If you mapped with field access, any method, except id, call initializes the proxy
assertFalse( Hibernate.isInitialized( o ) );
o.getName();
assertTrue( Hibernate.isInitialized( o ) );
s.close();
}
Expand Down
10 changes: 10 additions & 0 deletions hibernate-core/src/test/java/org/hibernate/property/Order.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class Order implements Serializable {
@Id
private int orderNumber;

private String name;

@OneToMany( fetch = FetchType.LAZY )
private Set<Item> items = new HashSet<Item>();

Expand All @@ -41,4 +43,12 @@ public void setOrderNumber(int orderNumber) {
public Set<Item> getItems() {
return items;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ public class GetterSetterSerializationTest {
public void testPrivateFieldGetter() throws Exception {
final AnEntity entity = new AnEntity( new PK( 1L ) );

final String propertyName = "pk";
final Getter getter = new GetterFieldImpl(
AnEntity.class,
"pk",
ReflectHelper.findField( AnEntity.class, "pk")
propertyName,
ReflectHelper.findField( AnEntity.class, propertyName)
);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream oos = new ObjectOutputStream(baos);
Expand All @@ -60,15 +61,16 @@ public void testPrivateFieldGetter() throws Exception {
public void testPrivateFieldSetter() throws Exception {
AnEntity entity = new AnEntity( new PK( 1L ) );

final String propertyName = "pk";
final Getter getter = new GetterFieldImpl(
AnEntity.class,
"pk",
ReflectHelper.findField( AnEntity.class, "pk")
propertyName,
ReflectHelper.findField( AnEntity.class, propertyName)
);
final Setter setter = new SetterFieldImpl(
AnEntity.class,
"pk",
ReflectHelper.findField( AnEntity.class, "pk")
propertyName,
ReflectHelper.findField( AnEntity.class, propertyName)
);

final ByteArrayOutputStream baos = new ByteArrayOutputStream();
Expand Down
Loading

0 comments on commit f8b78bc

Please sign in to comment.