Fix Delaying Basic attribute fetching
This commit is contained in:
parent
b872d8ad74
commit
18fee9cf5a
|
@ -83,6 +83,7 @@ public class ResultMementoEntityJpa implements ResultMementoEntity, FetchMemento
|
|||
)
|
||||
);
|
||||
|
||||
final boolean isEnhancedForLazyLoading = entityDescriptor.getRepresentationStrategy().isBytecodeEnhanced();
|
||||
// Implicit basic fetches are DELAYED by default, so register fetch builders for the remaining basic fetchables
|
||||
entityDescriptor.visitAttributeMappings(
|
||||
attributeMapping -> {
|
||||
|
@ -90,7 +91,8 @@ public class ResultMementoEntityJpa implements ResultMementoEntity, FetchMemento
|
|||
if ( attributeMapping instanceof BasicValuedModelPart ) {
|
||||
fetchBuilderCreator = k -> new DelayedFetchBuilderBasicPart(
|
||||
navigablePath.append( k ),
|
||||
(BasicValuedModelPart) attributeMapping
|
||||
(BasicValuedModelPart) attributeMapping,
|
||||
isEnhancedForLazyLoading
|
||||
);
|
||||
explicitFetchBuilderMap.computeIfAbsent(
|
||||
attributeMapping.getFetchableName(),
|
||||
|
|
|
@ -25,12 +25,15 @@ public class DelayedFetchBuilderBasicPart
|
|||
implements CompleteFetchBuilder, BasicValuedFetchBuilder, ModelPartReferenceBasic {
|
||||
private final NavigablePath navigablePath;
|
||||
private final BasicValuedModelPart referencedModelPart;
|
||||
private final boolean isEnhancedForLazyLoading;
|
||||
|
||||
public DelayedFetchBuilderBasicPart(
|
||||
NavigablePath navigablePath,
|
||||
BasicValuedModelPart referencedModelPart) {
|
||||
BasicValuedModelPart referencedModelPart,
|
||||
boolean isEnhancedForLazyLoading) {
|
||||
this.navigablePath = navigablePath;
|
||||
this.referencedModelPart = referencedModelPart;
|
||||
this.isEnhancedForLazyLoading = isEnhancedForLazyLoading;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -58,6 +61,7 @@ public class DelayedFetchBuilderBasicPart
|
|||
true,
|
||||
null,
|
||||
FetchTiming.DELAYED,
|
||||
isEnhancedForLazyLoading,
|
||||
domainResultCreationState
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.sql.results.graph;
|
||||
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
public class UnfetchedBasicPartResultAssembler<J> implements DomainResultAssembler<J> {
|
||||
|
||||
private final JavaTypeDescriptor<J> javaTypeDescriptor;
|
||||
|
||||
public UnfetchedBasicPartResultAssembler(JavaTypeDescriptor<J> javaTypeDescriptor) {
|
||||
this.javaTypeDescriptor = javaTypeDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public J assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<J> getAssembledJavaTypeDescriptor() {
|
||||
return javaTypeDescriptor;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
|||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.results.ResultsHelper;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
import org.hibernate.sql.results.graph.UnfetchedBasicPartResultAssembler;
|
||||
import org.hibernate.sql.results.graph.UnfetchedResultAssembler;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
|
@ -44,17 +45,44 @@ public class BasicFetch<T> implements Fetch, BasicResultGraphNode<T> {
|
|||
BasicValueConverter<T, ?> valueConverter,
|
||||
FetchTiming fetchTiming,
|
||||
DomainResultCreationState creationState) {
|
||||
this(
|
||||
valuesArrayPosition,
|
||||
fetchParent,
|
||||
fetchablePath,
|
||||
valuedMapping,
|
||||
nullable,
|
||||
valueConverter,
|
||||
fetchTiming,
|
||||
true,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
public BasicFetch(
|
||||
int valuesArrayPosition,
|
||||
FetchParent fetchParent,
|
||||
NavigablePath fetchablePath,
|
||||
BasicValuedModelPart valuedMapping,
|
||||
boolean nullable,
|
||||
BasicValueConverter<T, ?> valueConverter,
|
||||
FetchTiming fetchTiming,
|
||||
boolean canBasicPartFetchBeDelayed,
|
||||
DomainResultCreationState creationState) {
|
||||
this.nullable = nullable;
|
||||
this.navigablePath = fetchablePath;
|
||||
|
||||
this.fetchParent = fetchParent;
|
||||
this.valuedMapping = valuedMapping;
|
||||
this.fetchTiming = fetchTiming;
|
||||
@SuppressWarnings("unchecked")
|
||||
final JavaTypeDescriptor<T> javaTypeDescriptor = (JavaTypeDescriptor<T>) valuedMapping.getJavaTypeDescriptor();
|
||||
@SuppressWarnings("unchecked") final JavaTypeDescriptor<T> javaTypeDescriptor = (JavaTypeDescriptor<T>) valuedMapping.getJavaTypeDescriptor();
|
||||
// lazy basic attribute
|
||||
if ( fetchTiming == FetchTiming.DELAYED && valuesArrayPosition == -1 ) {
|
||||
this.assembler = new UnfetchedResultAssembler<>( javaTypeDescriptor );
|
||||
if ( canBasicPartFetchBeDelayed ) {
|
||||
this.assembler = new UnfetchedResultAssembler<>( javaTypeDescriptor );
|
||||
}
|
||||
else {
|
||||
this.assembler = new UnfetchedBasicPartResultAssembler( javaTypeDescriptor );
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.assembler = new BasicResultAssembler<>(
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test;
|
|||
import static org.hibernate.testing.orm.junit.ExtraAssertions.assertTyping;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -86,7 +87,8 @@ public class ResultMappingTest extends BaseSessionFactoryFunctionalTest {
|
|||
final ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
||||
final Object result = resultSetReturn.getSingleResult();
|
||||
assertTyping( H2ProcTesting.MyEntity.class, result );
|
||||
assertEquals( "Steve", ( (H2ProcTesting.MyEntity) result ).name );
|
||||
assertNull( ( (H2ProcTesting.MyEntity) result ).name );
|
||||
assertNotNull( ( (H2ProcTesting.MyEntity) result ).id );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue