Fix lazy loading of lazy basic attributes when an entity is fetched

This commit is contained in:
Andrea Boriero 2021-10-25 09:24:21 +02:00 committed by Steve Ebersole
parent 3dedb22365
commit 696eea9bbe
3 changed files with 98 additions and 5 deletions

View File

@ -282,7 +282,6 @@ public Fetch generateFetch(
// returning a domain result assembler that returns LazyPropertyInitializer.UNFETCHED_PROPERTY // returning a domain result assembler that returns LazyPropertyInitializer.UNFETCHED_PROPERTY
final EntityMappingType containingEntityMapping = findContainingEntityMapping(); final EntityMappingType containingEntityMapping = findContainingEntityMapping();
if ( fetchTiming == FetchTiming.DELAYED if ( fetchTiming == FetchTiming.DELAYED
&& fetchParent.getReferencedModePart() == containingEntityMapping
&& containingEntityMapping.getEntityPersister().getPropertyLaziness()[getStateArrayPosition()] ) { && containingEntityMapping.getEntityPersister().getPropertyLaziness()[getStateArrayPosition()] ) {
valuesArrayPosition = -1; valuesArrayPosition = -1;
} }

View File

@ -30,7 +30,6 @@
public class EntityJoinedFetchInitializer extends AbstractEntityInitializer { public class EntityJoinedFetchInitializer extends AbstractEntityInitializer {
private static final String CONCRETE_NAME = EntityJoinedFetchInitializer.class.getSimpleName(); private static final String CONCRETE_NAME = EntityJoinedFetchInitializer.class.getSimpleName();
private final ModelPart referencedModelPart;
private final boolean isEnhancedForLazyLoading; private final boolean isEnhancedForLazyLoading;
protected EntityJoinedFetchInitializer( protected EntityJoinedFetchInitializer(
@ -50,7 +49,6 @@ protected EntityJoinedFetchInitializer(
null, null,
creationState creationState
); );
this.referencedModelPart = referencedModelPart;
if ( getConcreteDescriptor() != null ) { if ( getConcreteDescriptor() != null ) {
this.isEnhancedForLazyLoading = getConcreteDescriptor().getBytecodeEnhancementMetadata() this.isEnhancedForLazyLoading = getConcreteDescriptor().getBytecodeEnhancementMetadata()
.isEnhancedForLazyLoading(); .isEnhancedForLazyLoading();
@ -62,6 +60,7 @@ protected EntityJoinedFetchInitializer(
@Override @Override
protected Object getProxy(PersistenceContext persistenceContext) { protected Object getProxy(PersistenceContext persistenceContext) {
ModelPart referencedModelPart = getInitializedPart();
if ( referencedModelPart instanceof ToOneAttributeMapping ) { if ( referencedModelPart instanceof ToOneAttributeMapping ) {
final boolean unwrapProxy = ( (ToOneAttributeMapping) referencedModelPart ).isUnwrapProxy() && isEnhancedForLazyLoading; final boolean unwrapProxy = ( (ToOneAttributeMapping) referencedModelPart ).isUnwrapProxy() && isEnhancedForLazyLoading;
if ( unwrapProxy ) { if ( unwrapProxy ) {

View File

@ -131,19 +131,87 @@ assert sessionFactory().getMetamodel()
@Test @Test
public void basicTypeLazyGroup() { public void basicTypeLazyGroup() {
inSession(
session -> {
final String qry = "select d from D d";
final Query query = session.createQuery( qry );
final ScrollableResults scrollableResults = getScrollableResults( query );
while ( scrollableResults.next() ) {
final DEntity dEntity = (DEntity) scrollableResults.get();
assertFalse( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) );
assertTrue( Hibernate.isPropertyInitialized( dEntity, "nonLazyString" ) );
}
}
);
inSession( inSession(
session -> { session -> {
final DEntity dEntity = session.get( DEntity.class, 1L ); final DEntity dEntity = session.get( DEntity.class, 1L );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "blob" ) ); assertFalse( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) ); assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) ); assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) );
assertTrue( Hibernate.isPropertyInitialized( dEntity, "nonLazyString" ) ); assertTrue( Hibernate.isPropertyInitialized( dEntity, "nonLazyString" ) );
dEntity.getBlob(); dEntity.getBlob();
assertTrue( Hibernate.isPropertyInitialized( dEntity, "blob" ) ); assertTrue( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertTrue( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) ); assertTrue( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) ); assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) );
} }
); );
inSession(
session -> {
final DEntity dEntity = session.get( DEntity.class, 1L );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) );
assertTrue( Hibernate.isPropertyInitialized( dEntity, "nonLazyString" ) );
dEntity.getBlob();
assertTrue( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertTrue( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) );
}
);
inSession(
session -> {
final String qry = "select e from E e join fetch e.d";
final Query query = session.createQuery( qry );
final List<EEntity> results = query.list();
results.forEach(
eEntity -> {
final DEntity dEntity = eEntity.getD();
assertFalse( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) );
assertTrue( Hibernate.isPropertyInitialized( dEntity, "nonLazyString" ) );
assertThat( dEntity.getNonLazyString(), is("I am not lazy") );
dEntity.getBlob();
assertTrue( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertTrue( Hibernate.isPropertyInitialized( dEntity, "lazyStringBlobGroup" ) );
assertThat( dEntity.getLazyStringBlobGroup(), is("I am lazy as a blob") );
assertFalse( Hibernate.isPropertyInitialized( dEntity, "lazyString" ) );
assertThat( dEntity.getLazyString(), is("I am lazy") );
}
);
}
);
} }
@Test @Test
@ -165,8 +233,8 @@ assert sessionFactory().getMetamodel()
while ( scrollableResults.next() ) { while ( scrollableResults.next() ) {
final EEntity eEntity = (EEntity) scrollableResults.get(); final EEntity eEntity = (EEntity) scrollableResults.get();
final DEntity dEntity = eEntity.getD(); final DEntity dEntity = eEntity.getD();
assertFalse(Hibernate.isPropertyInitialized( dEntity, "blob" )); assertFalse( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertTrue(Hibernate.isPropertyInitialized( dEntity, "nonLazyString" )); assertTrue( Hibernate.isPropertyInitialized( dEntity, "nonLazyString" ) );
} }
} }
); );
@ -628,6 +696,9 @@ public void prepareTestData() {
session -> { session -> {
DEntity d = new DEntity(); DEntity d = new DEntity();
d.setD( "bla" ); d.setD( "bla" );
d.setLazyString( "I am lazy" );
d.setNonLazyString( "I am not lazy" );
d.setLazyStringBlobGroup( "I am lazy as a blob" );
d.setOid( 1 ); d.setOid( 1 );
byte[] lBytes = "agdfagdfagfgafgsfdgasfdgfgasdfgadsfgasfdgasfdgasdasfdg".getBytes(); byte[] lBytes = "agdfagdfagfgafgsfdgasfdgfgasdfgadsfgasfdgasfdgasdasfdg".getBytes();
@ -959,6 +1030,30 @@ public GEntity getG() {
public void setG(GEntity g) { public void setG(GEntity g) {
this.g = g; this.g = g;
} }
public String getNonLazyString() {
return nonLazyString;
}
public void setNonLazyString(String nonLazyString) {
this.nonLazyString = nonLazyString;
}
public String getLazyString() {
return lazyString;
}
public void setLazyString(String lazyString) {
this.lazyString = lazyString;
}
public String getLazyStringBlobGroup() {
return lazyStringBlobGroup;
}
public void setLazyStringBlobGroup(String lazyStringBlobGroup) {
this.lazyStringBlobGroup = lazyStringBlobGroup;
}
} }
@Entity(name = "E") @Entity(name = "E")