Skip to content

Commit c3bd016

Browse files
committed
some minor refactorings to Initializers
1 parent ac3e9ca commit c3bd016

File tree

3 files changed

+228
-246
lines changed

3 files changed

+228
-246
lines changed

hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/AbstractBatchEntitySelectFetchInitializer.java

Lines changed: 129 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@
1111
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
1212
import org.hibernate.engine.spi.EntityHolder;
1313
import org.hibernate.engine.spi.EntityKey;
14-
import org.hibernate.engine.spi.PersistenceContext;
1514
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1615
import org.hibernate.metamodel.mapping.AttributeMapping;
1716
import org.hibernate.metamodel.mapping.EntityMappingType;
1817
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
1918
import org.hibernate.persister.entity.EntityPersister;
20-
import org.hibernate.proxy.HibernateProxy;
2119
import org.hibernate.proxy.LazyInitializer;
2220
import org.hibernate.spi.NavigablePath;
2321
import org.hibernate.sql.results.graph.AssemblerCreationState;
@@ -39,7 +37,8 @@ public abstract class AbstractBatchEntitySelectFetchInitializer<Data extends Abs
3937

4038
protected final EntityInitializer<InitializerData> owningEntityInitializer;
4139

42-
public static abstract class AbstractBatchEntitySelectFetchInitializerData extends EntitySelectFetchInitializerData {
40+
public static abstract class AbstractBatchEntitySelectFetchInitializerData
41+
extends EntitySelectFetchInitializerData {
4342
final boolean batchDisabled;
4443

4544
// per-row state
@@ -48,10 +47,11 @@ public static abstract class AbstractBatchEntitySelectFetchInitializerData exten
4847
public AbstractBatchEntitySelectFetchInitializerData(
4948
AbstractBatchEntitySelectFetchInitializer<?> initializer,
5049
RowProcessingState rowProcessingState) {
51-
super( initializer, rowProcessingState );
50+
super( rowProcessingState );
5251

5352
batchDisabled = rowProcessingState.isScrollResult()
54-
|| !rowProcessingState.getLoadQueryInfluencers().effectivelyBatchLoadable( initializer.toOneMapping.getEntityMappingType().getEntityPersister() );
53+
|| !rowProcessingState.getLoadQueryInfluencers()
54+
.effectivelyBatchLoadable( initializer.toOneMapping.getEntityMappingType().getEntityPersister() );
5555
}
5656
}
5757

@@ -65,66 +65,64 @@ public AbstractBatchEntitySelectFetchInitializer(
6565
AssemblerCreationState creationState) {
6666
super( parent, toOneMapping, fetchedNavigable, concreteDescriptor, keyResult, affectedByFilter, creationState );
6767
//noinspection unchecked
68-
this.owningEntityInitializer = (EntityInitializer<InitializerData>) Initializer.findOwningEntityInitializer( parent );
68+
this.owningEntityInitializer =
69+
(EntityInitializer<InitializerData>)
70+
Initializer.findOwningEntityInitializer( parent );
6971
assert owningEntityInitializer != null : "This initializer requires an owning parent entity initializer";
7072
}
7173

7274
protected abstract void registerResolutionListener(Data data);
7375

7476
@Override
7577
public void resolveKey(Data data) {
76-
if ( data.getState() != State.UNINITIALIZED ) {
77-
return;
78-
}
79-
80-
data.entityKey = null;
81-
data.setInstance( null );
82-
final RowProcessingState rowProcessingState = data.getRowProcessingState();
83-
//noinspection unchecked
84-
final Initializer<InitializerData> initializer = (Initializer<InitializerData>) keyAssembler.getInitializer();
85-
if ( initializer != null ) {
86-
final InitializerData subData = initializer.getData( rowProcessingState );
87-
initializer.resolveKey( subData );
88-
data.entityIdentifier = null;
89-
data.setState( subData.getState() == State.MISSING ? State.MISSING : State.KEY_RESOLVED );
90-
}
91-
else {
92-
data.entityIdentifier = keyAssembler.assemble( rowProcessingState );
93-
data.setState( data.entityIdentifier == null ? State.MISSING : State.KEY_RESOLVED );
78+
if ( data.getState() == State.UNINITIALIZED ) {
79+
data.entityKey = null;
80+
data.setInstance( null );
81+
final var rowProcessingState = data.getRowProcessingState();
82+
//noinspection unchecked
83+
final Initializer<InitializerData> initializer = (Initializer<InitializerData>) keyAssembler.getInitializer();
84+
if ( initializer != null ) {
85+
final InitializerData subData = initializer.getData( rowProcessingState );
86+
initializer.resolveKey( subData );
87+
data.entityIdentifier = null;
88+
data.setState( subData.getState() == State.MISSING ? State.MISSING : State.KEY_RESOLVED );
89+
}
90+
else {
91+
data.entityIdentifier = keyAssembler.assemble( rowProcessingState );
92+
data.setState( data.entityIdentifier == null ? State.MISSING : State.KEY_RESOLVED );
93+
}
9494
}
9595
}
9696

9797
@Override
9898
public void resolveInstance(Data data) {
99-
if ( data.getState() != State.KEY_RESOLVED ) {
100-
return;
101-
}
102-
103-
data.setState( State.RESOLVED );
104-
final RowProcessingState rowProcessingState = data.getRowProcessingState();
105-
if ( data.entityIdentifier == null ) {
106-
// entityIdentifier can be null if the identifier is based on an initializer
107-
data.entityIdentifier = keyAssembler.assemble( rowProcessingState );
99+
if ( data.getState() == State.KEY_RESOLVED ) {
100+
data.setState( State.RESOLVED );
101+
final var rowProcessingState = data.getRowProcessingState();
108102
if ( data.entityIdentifier == null ) {
109-
data.entityKey = null;
110-
data.setInstance( null );
111-
data.setState( State.MISSING );
112-
return;
103+
// entityIdentifier can be null if the identifier is based on an initializer
104+
data.entityIdentifier = keyAssembler.assemble( rowProcessingState );
105+
if ( data.entityIdentifier == null ) {
106+
data.entityKey = null;
107+
data.setInstance( null );
108+
data.setState( State.MISSING );
109+
return;
110+
}
113111
}
112+
resolveInstanceFromIdentifier( data );
114113
}
115-
resolveInstanceFromIdentifier( data );
116114
}
117115

118116
protected void resolveInstanceFromIdentifier(Data data) {
119117
if ( data.batchDisabled ) {
120-
initialize( data );
118+
initializeIfNecessary( data );
121119
}
122120
else {
123121
data.entityKey = new EntityKey( data.entityIdentifier, concreteDescriptor );
124122
data.setInstance( getExistingInitializedInstance( data ) );
125123
if ( data.getInstance() == null ) {
126-
// need to add the key to the batch queue only when the entity has not been already loaded or
127-
// there isn't another initializer that is loading it
124+
// need to add the key to the batch queue only when the entity has not
125+
// already been loaded or there's no other initializer that's loading it
128126
registerToBatchFetchQueue( data );
129127
}
130128
}
@@ -136,87 +134,92 @@ public void resolveInstance(Object instance, Data data) {
136134
data.setState( State.MISSING );
137135
data.entityKey = null;
138136
data.setInstance( null );
139-
return;
140137
}
141-
final RowProcessingState rowProcessingState = data.getRowProcessingState();
142-
// Only need to extract the identifier if the identifier has a many to one
143-
final LazyInitializer lazyInitializer = extractLazyInitializer( instance );
144-
data.entityKey = null;
145-
data.entityIdentifier = null;
146-
if ( lazyInitializer == null ) {
147-
// Entity is most probably initialized
148-
data.setInstance( instance );
149-
if ( concreteDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading()
150-
&& isPersistentAttributeInterceptable( instance )
151-
&& getAttributeInterceptor( instance )
152-
instanceof EnhancementAsProxyLazinessInterceptor enhancementInterceptor ) {
153-
if ( enhancementInterceptor.isInitialized() ) {
154-
data.setState( State.INITIALIZED );
138+
else {
139+
final var rowProcessingState = data.getRowProcessingState();
140+
// Only need to extract the identifier if the identifier has a many-to-one
141+
final LazyInitializer lazyInitializer = extractLazyInitializer( instance );
142+
data.entityKey = null;
143+
data.entityIdentifier = null;
144+
if ( lazyInitializer == null ) {
145+
// Entity is most probably initialized
146+
data.setInstance( instance );
147+
if ( concreteDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading()
148+
&& isPersistentAttributeInterceptable( instance )
149+
&& getAttributeInterceptor( instance )
150+
instanceof EnhancementAsProxyLazinessInterceptor enhancementInterceptor ) {
151+
if ( enhancementInterceptor.isInitialized() ) {
152+
data.setState( State.INITIALIZED );
153+
}
154+
else {
155+
data.setState( State.RESOLVED );
156+
data.entityIdentifier = enhancementInterceptor.getIdentifier();
157+
}
158+
if ( keyIsEager && data.entityIdentifier == null ) {
159+
data.entityIdentifier =
160+
concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
161+
}
155162
}
156163
else {
164+
// If the entity initializer is null, we know the entity is fully initialized.
165+
// Otherwise, it will be initialized by some other initializer.
157166
data.setState( State.RESOLVED );
158-
data.entityIdentifier = enhancementInterceptor.getIdentifier();
167+
data.entityIdentifier =
168+
concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
159169
}
160170
}
161-
else {
162-
// If the entity initializer is null, we know the entity is fully initialized,
163-
// otherwise it will be initialized by some other initializer
171+
else if ( lazyInitializer.isUninitialized() ) {
164172
data.setState( State.RESOLVED );
165-
data.entityIdentifier = concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
173+
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
166174
}
167-
if ( keyIsEager && data.entityIdentifier == null ) {
168-
data.entityIdentifier = concreteDescriptor.getIdentifier( instance, rowProcessingState.getSession() );
175+
else {
176+
// Entity is initialized
177+
data.setState( State.INITIALIZED );
178+
if ( keyIsEager ) {
179+
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
180+
}
181+
data.setInstance( lazyInitializer.getImplementation() );
182+
}
183+
184+
if ( data.getState() == State.RESOLVED ) {
185+
resolveInstanceFromIdentifier( data );
169186
}
170-
}
171-
else if ( lazyInitializer.isUninitialized() ) {
172-
data.setState( State.RESOLVED );
173-
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
174-
}
175-
else {
176-
// Entity is initialized
177-
data.setState( State.INITIALIZED );
178187
if ( keyIsEager ) {
179-
data.entityIdentifier = lazyInitializer.getInternalIdentifier();
188+
final Initializer<?> initializer = keyAssembler.getInitializer();
189+
assert initializer != null;
190+
initializer.resolveInstance( data.entityIdentifier, rowProcessingState );
191+
}
192+
else if ( rowProcessingState.needsResolveState() ) {
193+
// Resolve the state of the identifier if result caching is enabled and this is not a query cache hit
194+
keyAssembler.resolveState( rowProcessingState );
180195
}
181-
data.setInstance( lazyInitializer.getImplementation() );
182-
}
183-
184-
if ( data.getState() == State.RESOLVED ) {
185-
resolveInstanceFromIdentifier( data );
186-
}
187-
if ( keyIsEager ) {
188-
final Initializer<?> initializer = keyAssembler.getInitializer();
189-
assert initializer != null;
190-
initializer.resolveInstance( data.entityIdentifier, rowProcessingState );
191-
}
192-
else if ( rowProcessingState.needsResolveState() ) {
193-
// Resolve the state of the identifier if result caching is enabled and this is not a query cache hit
194-
keyAssembler.resolveState( rowProcessingState );
195196
}
196197
}
197198

198199
@Override
199200
public void initializeInstance(Data data) {
200-
if ( data.getState() != State.RESOLVED ) {
201-
return;
202-
}
203-
data.setState( State.INITIALIZED );
204-
if ( data.batchDisabled ) {
205-
Hibernate.initialize( data.getInstance() );
201+
if ( data.getState() == State.RESOLVED ) {
202+
data.setState( State.INITIALIZED );
203+
if ( data.batchDisabled ) {
204+
Hibernate.initialize( data.getInstance() );
205+
}
206206
}
207207
}
208208

209209
protected Object getExistingInitializedInstance(Data data) {
210-
final SharedSessionContractImplementor session = data.getRowProcessingState().getSession();
211-
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
212-
final EntityHolder holder = persistenceContext.getEntityHolder( data.entityKey );
210+
final EntityHolder holder =
211+
data.getRowProcessingState().getSession()
212+
.getPersistenceContextInternal()
213+
.getEntityHolder( data.entityKey );
213214
if ( holder != null && holder.getEntity() != null && holder.isEventuallyInitialized() ) {
214215
return holder.getEntity();
215216
}
216-
// we need to register a resolution listener only if there is not an already initialized instance
217-
// or an instance that another initializer is loading
218-
registerResolutionListener( data );
219-
return null;
217+
else {
218+
// we need to register a resolution listener only if there is not an already initialized instance
219+
// or an instance that another initializer is loading
220+
registerResolutionListener( data );
221+
return null;
222+
}
220223
}
221224

222225
protected void registerToBatchFetchQueue(Data data) {
@@ -238,7 +241,7 @@ public void initializeInstanceFromParent(Object parentInstance, Data data) {
238241
data.setState( State.MISSING );
239242
}
240243
else {
241-
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( instance );
244+
final LazyInitializer lazyInitializer = extractLazyInitializer( instance );
242245
if ( lazyInitializer != null && lazyInitializer.isUninitialized() ) {
243246
data.entityKey = new EntityKey( lazyInitializer.getInternalIdentifier(), concreteDescriptor );
244247
registerToBatchFetchQueue( data );
@@ -259,40 +262,35 @@ protected static Object loadInstance(
259262
toOneMapping.isInternalLoadNullable()
260263
);
261264
if ( instance == null ) {
262-
if ( toOneMapping.getNotFoundAction() != NotFoundAction.IGNORE ) {
263-
if ( affectedByFilter ) {
264-
throw new EntityFilterException(
265-
entityKey.getEntityName(),
266-
entityKey.getIdentifier(),
267-
toOneMapping.getNavigableRole().getFullPath()
268-
);
269-
}
270-
if ( toOneMapping.getNotFoundAction() == NotFoundAction.EXCEPTION ) {
271-
throw new FetchNotFoundException( entityKey.getEntityName(), entityKey.getIdentifier() );
272-
}
273-
}
265+
handleNotFound( entityKey, toOneMapping, affectedByFilter );
274266
}
275267
return instance;
276268
}
277269

270+
private static void handleNotFound(EntityKey entityKey, ToOneAttributeMapping toOneMapping, boolean affectedByFilter) {
271+
final NotFoundAction notFoundAction = toOneMapping.getNotFoundAction(); // can be null
272+
if ( affectedByFilter ) {
273+
if ( notFoundAction != NotFoundAction.IGNORE ) {
274+
throw new EntityFilterException( entityKey.getEntityName(), entityKey.getIdentifier(),
275+
toOneMapping.getNavigableRole().getFullPath() );
276+
}
277+
}
278+
else {
279+
if ( notFoundAction == NotFoundAction.EXCEPTION ) {
280+
throw new FetchNotFoundException( entityKey.getEntityName(), entityKey.getIdentifier() );
281+
}
282+
}
283+
}
284+
278285
protected AttributeMapping[] getParentEntityAttributes(String attributeName) {
279286
final EntityPersister entityDescriptor = owningEntityInitializer.getEntityDescriptor();
280-
final AttributeMapping[] parentEntityAttributes = new AttributeMapping[
281-
entityDescriptor.getRootEntityDescriptor()
282-
.getSubclassEntityNames()
283-
.size()
284-
];
285-
parentEntityAttributes[entityDescriptor.getSubclassId()] = getParentEntityAttribute(
286-
entityDescriptor,
287-
toOneMapping,
288-
attributeName
289-
);
290-
for ( EntityMappingType subMappingType : entityDescriptor.getSubMappingTypes() ) {
291-
parentEntityAttributes[subMappingType.getSubclassId()] = getParentEntityAttribute(
292-
subMappingType,
293-
toOneMapping,
294-
attributeName
295-
);
287+
final int size = entityDescriptor.getRootEntityDescriptor().getSubclassEntityNames().size();
288+
final AttributeMapping[] parentEntityAttributes = new AttributeMapping[size];
289+
parentEntityAttributes[entityDescriptor.getSubclassId()] =
290+
getParentEntityAttribute( entityDescriptor, toOneMapping, attributeName );
291+
for ( var subMappingType : entityDescriptor.getSubMappingTypes() ) {
292+
parentEntityAttributes[subMappingType.getSubclassId()] =
293+
getParentEntityAttribute( subMappingType, toOneMapping, attributeName );
296294
}
297295
return parentEntityAttributes;
298296
}
@@ -302,8 +300,9 @@ protected static AttributeMapping getParentEntityAttribute(
302300
ToOneAttributeMapping referencedModelPart,
303301
String attributeName) {
304302
final AttributeMapping parentAttribute = subMappingType.findAttributeMapping( attributeName );
305-
if ( parentAttribute != null && parentAttribute.getDeclaringType() == referencedModelPart.getDeclaringType()
306-
.findContainingEntityMapping() ) {
303+
if ( parentAttribute != null
304+
&& parentAttribute.getDeclaringType()
305+
== referencedModelPart.getDeclaringType().findContainingEntityMapping() ) {
307306
// These checks are needed to avoid setting the instance using the wrong (child's) model part or
308307
// setting it multiple times in case parent and child share the same attribute name for the association.
309308
return parentAttribute;

0 commit comments

Comments
 (0)