HHH-17188 Eagerly select values when query cache is enabled
This commit is contained in:
parent
c84a30c2c5
commit
c0c628f16c
|
@ -668,6 +668,13 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveState(RowProcessingState rowProcessingState) {
|
||||||
|
for ( DomainResultAssembler<?> subAssembler : subAssemblers ) {
|
||||||
|
subAssembler.resolveState( rowProcessingState );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JavaType<Object[]> getAssembledJavaType() {
|
public JavaType<Object[]> getAssembledJavaType() {
|
||||||
return jtd;
|
return jtd;
|
||||||
|
|
|
@ -38,4 +38,12 @@ public interface DomainResultAssembler<J> {
|
||||||
* assembles.
|
* assembles.
|
||||||
*/
|
*/
|
||||||
JavaType<J> getAssembledJavaType();
|
JavaType<J> getAssembledJavaType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to resolve the assembler's state, i.e. reading the result values,
|
||||||
|
* with some performance optimization when we don't need the result object itself
|
||||||
|
*/
|
||||||
|
default void resolveState(RowProcessingState rowProcessingState) {
|
||||||
|
assemble( rowProcessingState );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,11 @@ public class BasicResultAssembler<J> implements DomainResultAssembler<J> {
|
||||||
return (J) jdbcValue;
|
return (J) jdbcValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveState(RowProcessingState rowProcessingState) {
|
||||||
|
extractRawValue( rowProcessingState );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JavaType<J> getAssembledJavaType() {
|
public JavaType<J> getAssembledJavaType() {
|
||||||
if ( valueConverter != null ) {
|
if ( valueConverter != null ) {
|
||||||
|
|
|
@ -323,6 +323,15 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
||||||
state = stateAllNull ? State.NULL : State.EXTRACTED;
|
state = stateAllNull ? State.NULL : State.EXTRACTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveState(RowProcessingState rowProcessingState) {
|
||||||
|
if ( determinInitialState() == State.INITIAL ) {
|
||||||
|
for ( final DomainResultAssembler<?> assembler : assemblers ) {
|
||||||
|
assembler.resolveState( rowProcessingState );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Object createCompositeInstance(NavigablePath navigablePath, SessionFactoryImplementor sessionFactory) {
|
private Object createCompositeInstance(NavigablePath navigablePath, SessionFactoryImplementor sessionFactory) {
|
||||||
if ( state == State.NULL ) {
|
if ( state == State.NULL ) {
|
||||||
// todo (6.0) : should we initialize the composite instance if it has a parent attribute?
|
// todo (6.0) : should we initialize the composite instance if it has a parent attribute?
|
||||||
|
|
|
@ -48,4 +48,6 @@ public interface EmbeddableInitializer extends FetchParentAccess {
|
||||||
default EmbeddableInitializer asEmbeddableInitializer() {
|
default EmbeddableInitializer asEmbeddableInitializer() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resolveState(RowProcessingState rowProcessingState);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||||
import org.hibernate.sql.results.graph.Fetchable;
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.graph.Initializer;
|
import org.hibernate.sql.results.graph.Initializer;
|
||||||
|
import org.hibernate.sql.results.graph.embeddable.AbstractEmbeddableInitializer;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableLoadingLogger;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableLoadingLogger;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
||||||
|
@ -158,9 +159,7 @@ public abstract class AbstractNonAggregatedIdentifierMappingInitializer extends
|
||||||
return;
|
return;
|
||||||
case INITIAL:
|
case INITIAL:
|
||||||
// If we don't have an id class and this is a find by id lookup, we just use that instance
|
// If we don't have an id class and this is a find by id lookup, we just use that instance
|
||||||
if ( !hasIdClass && processingState.getEntityId() != null
|
if ( isFindByIdLookup( processingState ) ) {
|
||||||
&& navigablePath.getParent().getParent() == null
|
|
||||||
&& navigablePath instanceof EntityIdentifierNavigablePath ) {
|
|
||||||
compositeInstance = processingState.getEntityId();
|
compositeInstance = processingState.getEntityId();
|
||||||
state = State.INJECTED;
|
state = State.INJECTED;
|
||||||
return;
|
return;
|
||||||
|
@ -216,6 +215,12 @@ public abstract class AbstractNonAggregatedIdentifierMappingInitializer extends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isFindByIdLookup(RowProcessingState processingState) {
|
||||||
|
return !hasIdClass && processingState.getEntityId() != null
|
||||||
|
&& navigablePath.getParent().getParent() == null
|
||||||
|
&& navigablePath instanceof EntityIdentifierNavigablePath;
|
||||||
|
}
|
||||||
|
|
||||||
private void extractRowState(RowProcessingState processingState) {
|
private void extractRowState(RowProcessingState processingState) {
|
||||||
state = State.NULL;
|
state = State.NULL;
|
||||||
for ( int i = 0; i < assemblers.length; i++ ) {
|
for ( int i = 0; i < assemblers.length; i++ ) {
|
||||||
|
@ -256,6 +261,15 @@ public abstract class AbstractNonAggregatedIdentifierMappingInitializer extends
|
||||||
state = State.EXTRACTED;
|
state = State.EXTRACTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveState(RowProcessingState rowProcessingState) {
|
||||||
|
if ( !isFindByIdLookup( rowProcessingState ) ) {
|
||||||
|
for ( final DomainResultAssembler<?> assembler : assemblers ) {
|
||||||
|
assembler.resolveState( rowProcessingState );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getValues() {
|
public Object[] getValues() {
|
||||||
return state == State.NULL ? null : idClassState;
|
return state == State.NULL ? null : idClassState;
|
||||||
|
|
|
@ -35,4 +35,10 @@ public class EmbeddableAssembler implements DomainResultAssembler {
|
||||||
return initializer.getCompositeInstance();
|
return initializer.getCompositeInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolveState(RowProcessingState rowProcessingState) {
|
||||||
|
// use resolveState instead of initialize instance to avoid
|
||||||
|
// unneeded embeddable instantiation and injection
|
||||||
|
initializer.resolveState( rowProcessingState );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -517,6 +517,10 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
this.isInitialized = true;
|
this.isInitialized = true;
|
||||||
registerReloadedEntity( rowProcessingState, existingEntity );
|
registerReloadedEntity( rowProcessingState, existingEntity );
|
||||||
notifyResolutionListeners( entityInstance );
|
notifyResolutionListeners( entityInstance );
|
||||||
|
if ( rowProcessingState.getQueryOptions().isResultCachingEnabled() == Boolean.TRUE ) {
|
||||||
|
// We still need to read result set values to correctly populate the query cache
|
||||||
|
resolveState( rowProcessingState );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
registerLoadingEntityInstanceFromExecutionContext( rowProcessingState, entityInstance );
|
registerLoadingEntityInstanceFromExecutionContext( rowProcessingState, entityInstance );
|
||||||
|
@ -1062,6 +1066,14 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resolveState(RowProcessingState rowProcessingState) {
|
||||||
|
for ( final DomainResultAssembler<?> assembler : assemblers[concreteDescriptor.getSubclassId()] ) {
|
||||||
|
if ( assembler != null ) {
|
||||||
|
assembler.resolveState( rowProcessingState );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean skipInitialization(Object toInitialize, RowProcessingState rowProcessingState) {
|
protected boolean skipInitialization(Object toInitialize, RowProcessingState rowProcessingState) {
|
||||||
if ( !isOwningInitializer ) {
|
if ( !isOwningInitializer ) {
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue