Skip to content

Commit

Permalink
HHH-13094 - Respect @Any.fetch setting to FetchType.EAGER
Browse files Browse the repository at this point in the history
  • Loading branch information
johnlinp authored and vladmihalcea committed Dec 18, 2018
1 parent 7358893 commit 08747fc
Show file tree
Hide file tree
Showing 17 changed files with 393 additions and 24 deletions.
Expand Up @@ -2343,6 +2343,9 @@ private void bindAny(
Any anyBinding,
final AttributeRole attributeRole,
AttributePath attributePath) {

anyBinding.setLazy( anyMapping.isLazy() );

final TypeResolution keyTypeResolution = resolveType(
sourceDocument,
anyMapping.getKeySource().getTypeSource()
Expand Down
Expand Up @@ -268,4 +268,9 @@ public AnyKeySource getKeySource() {
public String getCascadeStyleName() {
return jaxbAnyMapping.getCascade();
}

@Override
public boolean isLazy() {
return isBytecodeLazy();
}
}
Expand Up @@ -15,4 +15,8 @@
public interface AnyMappingSource {
AnyDiscriminatorSource getDiscriminatorSource();
AnyKeySource getKeySource();

default boolean isLazy() {
return true;
}
}
Expand Up @@ -3272,12 +3272,14 @@ private static void bindAny(
+ BinderHelper.getPath( propertyHolder, inferredData )
);
}
boolean lazy = ( anyAnn.fetch() == FetchType.LAZY );
Any value = BinderHelper.buildAnyValue(
anyAnn.metaDef(),
columns,
anyAnn.metaColumn(),
inferredData,
cascadeOnDelete,
lazy,
nullability,
propertyHolder,
entityBinder,
Expand All @@ -3289,7 +3291,7 @@ private static void bindAny(
binder.setName( inferredData.getPropertyName() );
binder.setValue( value );

binder.setLazy( anyAnn.fetch() == FetchType.LAZY );
binder.setLazy( lazy );
//binder.setCascade(cascadeStrategy);
if ( isIdentifierMapper ) {
binder.setInsertable( false );
Expand Down
Expand Up @@ -941,6 +941,7 @@ public static Any buildAnyValue(
javax.persistence.Column metaColumn,
PropertyData inferredData,
boolean cascadeOnDelete,
boolean lazy,
Nullability nullability,
PropertyHolder propertyHolder,
EntityBinder entityBinder,
Expand All @@ -950,6 +951,7 @@ public static Any buildAnyValue(
Any value = new Any( context, columns[0].getTable() );
AnyMetaDef metaAnnDef = inferredData.getProperty().getAnnotation( AnyMetaDef.class );

value.setLazy( lazy );
if ( metaAnnDef != null ) {
//local has precedence over general and can be mapped for future reference if named
bindAnyMetaDefs( inferredData.getProperty(), context );
Expand Down
Expand Up @@ -1494,6 +1494,7 @@ else if ( anyAnn != null ) {
anyAnn.metaColumn(),
inferredData,
cascadeDeleteEnabled,
anyAnn.fetch() == FetchType.LAZY,
Nullability.NO_CONSTRAINT,
propertyHolder,
new EntityBinder(),
Expand Down
15 changes: 13 additions & 2 deletions hibernate-core/src/main/java/org/hibernate/mapping/Any.java
Expand Up @@ -24,6 +24,7 @@ public class Any extends SimpleValue {
private String identifierTypeName;
private String metaTypeName = "string";
private Map metaValues;
private boolean lazy = true;

/**
* @deprecated Use {@link Any#Any(MetadataBuildingContext, Table)} instead.
Expand All @@ -50,7 +51,8 @@ public Type getType() throws MappingException {

return getMetadata().getTypeResolver().getTypeFactory().any(
metaValues == null ? metaType : new MetaType( metaValues, metaType ),
getMetadata().getTypeResolver().heuristicType( identifierTypeName )
getMetadata().getTypeResolver().heuristicType( identifierTypeName ),
isLazy()
);
}

Expand All @@ -72,6 +74,14 @@ public void setMetaValues(Map metaValues) {
this.metaValues = metaValues;
}

public boolean isLazy() {
return lazy;
}

public void setLazy(boolean lazy) {
this.lazy = lazy;
}

public void setTypeUsingReflection(String className, String propertyName)
throws MappingException {
}
Expand All @@ -89,6 +99,7 @@ public boolean isSame(Any other) {
return super.isSame( other )
&& Objects.equals( identifierTypeName, other.identifierTypeName )
&& Objects.equals( metaTypeName, other.metaTypeName )
&& Objects.equals( metaValues, other.metaValues );
&& Objects.equals( metaValues, other.metaValues )
&& lazy == other.lazy;
}
}
12 changes: 7 additions & 5 deletions hibernate-core/src/main/java/org/hibernate/type/AnyType.java
Expand Up @@ -47,18 +47,20 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT
private final TypeFactory.TypeScope scope;
private final Type identifierType;
private final Type discriminatorType;
private final boolean eager;

/**
* Intended for use only from legacy {@link ObjectType} type definition
*/
protected AnyType(Type discriminatorType, Type identifierType) {
this( null, discriminatorType, identifierType );
this( null, discriminatorType, identifierType, true );
}

public AnyType(TypeFactory.TypeScope scope, Type discriminatorType, Type identifierType) {
public AnyType(TypeFactory.TypeScope scope, Type discriminatorType, Type identifierType, boolean lazy) {
this.scope = scope;
this.discriminatorType = discriminatorType;
this.identifierType = identifierType;
this.eager = !lazy;
}

public Type getIdentifierType() {
Expand Down Expand Up @@ -266,7 +268,7 @@ private Object resolveAny(String entityName, Serializable id, SharedSessionContr
throws HibernateException {
return entityName==null || id==null
? null
: session.internalLoad( entityName, id, false, false );
: session.internalLoad( entityName, id, eager, false );
}

@Override
Expand Down Expand Up @@ -319,7 +321,7 @@ public String toLoggableString(Object value, SessionFactoryImplementor factory)
@Override
public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner) throws HibernateException {
final ObjectTypeCacheEntry e = (ObjectTypeCacheEntry) cached;
return e == null ? null : session.internalLoad( e.entityName, e.id, false, false );
return e == null ? null : session.internalLoad( e.entityName, e.id, eager, false );
}

@Override
Expand Down Expand Up @@ -348,7 +350,7 @@ public Object replace(Object original, Object target, SharedSessionContractImple
else {
final String entityName = session.bestGuessEntityName( original );
final Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, original, session );
return session.internalLoad( entityName, id, false, false );
return session.internalLoad( entityName, id, eager, false );
}
}

Expand Down
23 changes: 22 additions & 1 deletion hibernate-core/src/main/java/org/hibernate/type/TypeFactory.java
Expand Up @@ -401,7 +401,28 @@ public EmbeddedComponentType embeddedComponent(ComponentMetamodel metamodel) {

// any type builder ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/**
* Get the AnyType with the specified parameters.
*
* @param metaType meta type
* @param identifierType identifier type
* @return AnyType
* @deprecated use {@link TypeFactory#any(Type, Type, boolean)} instead
*/
@Deprecated
public Type any(Type metaType, Type identifierType) {
return new AnyType( typeScope, metaType, identifierType );
return any( metaType, identifierType, true );
}

/**
* Get the AnyType with the specified parameters.
*
* @param metaType meta type
* @param identifierType identifier type
* @param lazy is teh underlying proeprty lazy
* @return AnyType
*/
public Type any(Type metaType, Type identifierType, boolean lazy) {
return new AnyType( typeScope, metaType, identifierType, lazy );
}
}
Expand Up @@ -6,18 +6,27 @@
*/
package org.hibernate.test.annotations.any;

import org.junit.Test;

import org.hibernate.Query;
import org.hibernate.LazyInitializationException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;

import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;

import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class AnyTest extends BaseCoreFunctionalTestCase {

@Override
protected boolean isCleanupTestDataRequired() {
return true;
}

@Test
public void testDefaultAnyAssociation() {
Session s = openSession();
Expand All @@ -26,13 +35,13 @@ public void testDefaultAnyAssociation() {
PropertySet set1 = new PropertySet( "string" );
Property property = new StringProperty( "name", "Alex" );
set1.setSomeProperty( property );
set1.addGeneratedProperty( property );
set1.addGeneralProperty( property );
s.save( set1 );

PropertySet set2 = new PropertySet( "integer" );
property = new IntegerProperty( "age", 33 );
set2.setSomeProperty( property );
set2.addGeneratedProperty( property );
set2.addGeneralProperty( property );
s.save( set2 );

s.flush();
Expand Down Expand Up @@ -116,10 +125,10 @@ public void testMetaDataUseWithManyToAny() throws Exception {

list.setSomeProperty( longProperty );

list.addGeneratedProperty( stringProperty );
list.addGeneratedProperty( integerProperty );
list.addGeneratedProperty( longProperty );
list.addGeneratedProperty( charProp );
list.addGeneralProperty( stringProperty );
list.addGeneralProperty( integerProperty );
list.addGeneralProperty( longProperty );
list.addGeneralProperty( charProp );

s.save( list );

Expand Down Expand Up @@ -151,13 +160,65 @@ public void testMetaDataUseWithManyToAny() throws Exception {
s.close();
}

@Test
public void testFetchEager() {
doInHibernate( this::sessionFactory, s -> {
PropertySet set = new PropertySet( "string" );
Property property = new StringProperty( "name", "Alex" );
set.setSomeProperty( property );
s.save( set );
} );

PropertySet result = doInHibernate( this::sessionFactory, s -> {
return s.createQuery( "select s from PropertySet s where name = :name", PropertySet.class )
.setParameter( "name", "string" )
.getSingleResult();
} );

assertNotNull( result );
assertNotNull( result.getSomeProperty() );
assertTrue( result.getSomeProperty() instanceof StringProperty );
assertEquals( "Alex", result.getSomeProperty().asString() );
}

@Test
public void testFetchLazy() {
doInHibernate( this::sessionFactory, s -> {
LazyPropertySet set = new LazyPropertySet( "string" );
Property property = new StringProperty( "name", "Alex" );
set.setSomeProperty( property );
s.save( set );
} );

LazyPropertySet result = doInHibernate( this::sessionFactory, s -> {
return s.createQuery( "select s from LazyPropertySet s where name = :name", LazyPropertySet.class )
.setParameter( "name", "string" )
.getSingleResult();
} );

assertNotNull( result );
assertNotNull( result.getSomeProperty() );

try {
result.getSomeProperty().asString();
fail( "should not get the property string after session closed." );
}
catch (LazyInitializationException e) {
// expected
}
catch (Exception e) {
fail( "should not throw exception other than LazyInitializationException." );
}
}

@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
StringProperty.class,
IntegerProperty.class,
LongProperty.class,
PropertySet.class,
LazyPropertySet.class,
PropertyMap.class,
PropertyList.class,
CharProperty.class
Expand All @@ -172,8 +233,8 @@ protected String[] getAnnotatedPackages() {
}

// Simply having this orm.xml file in the classpath reproduces HHH-4261.
@Override
protected String[] getXmlFiles() {
return new String[] { "org/hibernate/test/annotations/any/orm.xml" };
}
@Override
protected String[] getXmlFiles() {
return new String[] { "org/hibernate/test/annotations/any/orm.xml" };
}
}

0 comments on commit 08747fc

Please sign in to comment.