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 class BasicAttributeMapping
// returning a domain result assembler that returns LazyPropertyInitializer.UNFETCHED_PROPERTY
final EntityMappingType containingEntityMapping = findContainingEntityMapping();
if ( fetchTiming == FetchTiming.DELAYED
&& fetchParent.getReferencedModePart() == containingEntityMapping
&& containingEntityMapping.getEntityPersister().getPropertyLaziness()[getStateArrayPosition()] ) {
valuesArrayPosition = -1;
}

View File

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

View File

@ -131,19 +131,87 @@ public class FetchGraphTest extends BaseNonConfigCoreFunctionalTestCase {
@Test
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(
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 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
@ -165,8 +233,8 @@ public class FetchGraphTest extends BaseNonConfigCoreFunctionalTestCase {
while ( scrollableResults.next() ) {
final EEntity eEntity = (EEntity) scrollableResults.get();
final DEntity dEntity = eEntity.getD();
assertFalse(Hibernate.isPropertyInitialized( dEntity, "blob" ));
assertTrue(Hibernate.isPropertyInitialized( dEntity, "nonLazyString" ));
assertFalse( Hibernate.isPropertyInitialized( dEntity, "blob" ) );
assertTrue( Hibernate.isPropertyInitialized( dEntity, "nonLazyString" ) );
}
}
);
@ -628,6 +696,9 @@ public class FetchGraphTest extends BaseNonConfigCoreFunctionalTestCase {
session -> {
DEntity d = new DEntity();
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 );
byte[] lBytes = "agdfagdfagfgafgsfdgasfdgfgasdfgadsfgasfdgasfdgasdasfdg".getBytes();
@ -959,6 +1030,30 @@ public class FetchGraphTest extends BaseNonConfigCoreFunctionalTestCase {
public void setG(GEntity 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")