Skip to content

Commit 77d7deb

Browse files
gbadnersebersole
authored andcommitted
HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)
1 parent d6ac535 commit 77d7deb

File tree

6 files changed

+82
-78
lines changed

6 files changed

+82
-78
lines changed

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AbstractCompositeEntityIdentifierDescription.java

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -64,53 +64,4 @@ public FetchSource getSource() {
6464
// the source for this (as a Fetch) is the entity reference
6565
return entityReference;
6666
}
67-
68-
@Override
69-
protected EntityFetch createEntityFetch(
70-
AssociationAttributeDefinition attributeDefinition,
71-
FetchStrategy fetchStrategy,
72-
Join fetchedJoin,
73-
LoadPlanBuildingContext loadPlanBuildingContext) {
74-
// we have a key-many-to-one
75-
//
76-
// IMPL NOTE: we pass ourselves as the ExpandingFetchSource to collect fetches and later build
77-
// the IdentifierDescription
78-
79-
// if `this` is a fetch and its owner is "the same" (bi-directionality) as the attribute to be join fetched
80-
// we should wrap our FetchSource as an EntityFetch. That should solve everything except for the alias
81-
// context lookups because of the different instances (because of wrapping). So somehow the consumer of this
82-
// needs to be able to unwrap it to do the alias lookup, and would have to know to do that.
83-
//
84-
//
85-
// we are processing the EntityReference(Address) identifier. we come across its key-many-to-one reference
86-
// to Person. Now, if EntityReference(Address) is an instance of EntityFetch(Address) there is a strong
87-
// likelihood that we have a bi-directionality and need to handle that specially.
88-
//
89-
// how to best (a) find the bi-directionality and (b) represent that?
90-
91-
final FetchSource registeredFetchSource = loadPlanBuildingContext.registeredFetchSource(
92-
attributeDefinition.getAssociationKey()
93-
);
94-
if ( isKeyManyToOneBidirectionalAttributeDefinition( attributeDefinition, loadPlanBuildingContext ) ) {
95-
return new KeyManyToOneBidirectionalEntityFetchImpl(
96-
this,
97-
attributeDefinition,
98-
fetchStrategy,
99-
fetchedJoin,
100-
registeredFetchSource.resolveEntityReference()
101-
);
102-
}
103-
else {
104-
return super.createEntityFetch( attributeDefinition, fetchStrategy, fetchedJoin, loadPlanBuildingContext );
105-
}
106-
}
107-
108-
private boolean isKeyManyToOneBidirectionalAttributeDefinition(
109-
AssociationAttributeDefinition attributeDefinition,
110-
LoadPlanBuildingContext loadPlanBuildingContext) {
111-
final FetchSource registeredFetchSource = loadPlanBuildingContext.registeredFetchSource(
112-
attributeDefinition.getAssociationKey()
113-
);
114-
return registeredFetchSource != null && registeredFetchSource != getSource();
115-
}
11667
}

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AbstractCompositeFetch.java

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.hibernate.loader.plan2.build.spi.ExpandingFetchSource;
3434
import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpace;
3535
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
36+
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
3637
import org.hibernate.loader.plan2.spi.CollectionFetch;
3738
import org.hibernate.loader.plan2.spi.CompositeFetch;
3839
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
@@ -120,6 +121,25 @@ public EntityFetch buildEntityFetch(
120121
AssociationAttributeDefinition attributeDefinition,
121122
FetchStrategy fetchStrategy,
122123
LoadPlanBuildingContext loadPlanBuildingContext) {
124+
return buildEntityFetch( attributeDefinition, fetchStrategy, null, loadPlanBuildingContext );
125+
}
126+
127+
@Override
128+
public BidirectionalEntityFetch buildBidirectionalEntityFetch(
129+
AssociationAttributeDefinition attributeDefinition,
130+
FetchStrategy fetchStrategy,
131+
EntityReference entityReference,
132+
LoadPlanBuildingContext loadPlanBuildingContext) {
133+
return (BidirectionalEntityFetch) buildEntityFetch(
134+
attributeDefinition, fetchStrategy, entityReference, loadPlanBuildingContext
135+
);
136+
}
137+
138+
private EntityFetch buildEntityFetch(
139+
AssociationAttributeDefinition attributeDefinition,
140+
FetchStrategy fetchStrategy,
141+
EntityReference targetEntityReference,
142+
LoadPlanBuildingContext loadPlanBuildingContext) {
123143
final EntityType fetchedType = (EntityType) attributeDefinition.getType();
124144
final EntityPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getEntityPersister(
125145
fetchedType.getAssociatedEntityName()
@@ -144,25 +164,17 @@ public EntityFetch buildEntityFetch(
144164
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid(),
145165
attributeDefinition.isNullable()
146166
);
147-
final EntityFetch fetch = createEntityFetch( attributeDefinition, fetchStrategy, join, loadPlanBuildingContext );
167+
final EntityFetch fetch;
168+
if ( targetEntityReference == null ) {
169+
fetch = new EntityFetchImpl( this, attributeDefinition, fetchStrategy, join );
170+
}
171+
else {
172+
fetch = new BidirectionalEntityFetchImpl( this, attributeDefinition, fetchStrategy, join, targetEntityReference );
173+
}
148174
addFetch( fetch );
149175
return fetch;
150176
}
151177

152-
protected EntityFetch createEntityFetch(
153-
AssociationAttributeDefinition attributeDefinition,
154-
FetchStrategy fetchStrategy,
155-
Join fetchedJoin,
156-
LoadPlanBuildingContext loadPlanBuildingContext) {
157-
return new EntityFetchImpl(
158-
this,
159-
attributeDefinition,
160-
fetchStrategy,
161-
fetchedJoin
162-
);
163-
164-
}
165-
166178
private void addFetch(Fetch fetch) {
167179
if ( fetches == null ) {
168180
fetches = new ArrayList<Fetch>();

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/returns/AbstractEntityReference.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.hibernate.loader.plan2.build.spi.ExpandingFetchSource;
3333
import org.hibernate.loader.plan2.build.spi.ExpandingQuerySpace;
3434
import org.hibernate.loader.plan2.build.spi.LoadPlanBuildingContext;
35+
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
3536
import org.hibernate.loader.plan2.spi.CollectionFetch;
3637
import org.hibernate.loader.plan2.spi.CompositeFetch;
3738
import org.hibernate.loader.plan2.spi.CompositeQuerySpace;
@@ -155,6 +156,26 @@ public EntityFetch buildEntityFetch(
155156
AssociationAttributeDefinition attributeDefinition,
156157
FetchStrategy fetchStrategy,
157158
LoadPlanBuildingContext loadPlanBuildingContext) {
159+
return buildEntityFetch( attributeDefinition, fetchStrategy, null, loadPlanBuildingContext );
160+
}
161+
162+
@Override
163+
public BidirectionalEntityFetch buildBidirectionalEntityFetch(
164+
AssociationAttributeDefinition attributeDefinition,
165+
FetchStrategy fetchStrategy,
166+
EntityReference targetEntityReference,
167+
LoadPlanBuildingContext loadPlanBuildingContext) {
168+
return (BidirectionalEntityFetch) buildEntityFetch(
169+
attributeDefinition, fetchStrategy, targetEntityReference, loadPlanBuildingContext
170+
);
171+
}
172+
173+
174+
private EntityFetch buildEntityFetch(
175+
AssociationAttributeDefinition attributeDefinition,
176+
FetchStrategy fetchStrategy,
177+
EntityReference targetEntityReference,
178+
LoadPlanBuildingContext loadPlanBuildingContext) {
158179
final EntityType fetchedType = (EntityType) attributeDefinition.getType();
159180
final EntityPersister fetchedPersister = loadPlanBuildingContext.getSessionFactory().getEntityPersister(
160181
fetchedType.getAssociatedEntityName()
@@ -177,12 +198,13 @@ public EntityFetch buildEntityFetch(
177198
loadPlanBuildingContext.getQuerySpaces().generateImplicitUid(),
178199
attributeDefinition.isNullable()
179200
);
180-
final EntityFetch fetch = new EntityFetchImpl(
181-
this,
182-
attributeDefinition,
183-
fetchStrategy,
184-
join
185-
);
201+
final EntityFetch fetch;
202+
if ( targetEntityReference == null ) {
203+
fetch = new EntityFetchImpl( this, attributeDefinition, fetchStrategy, join );
204+
}
205+
else {
206+
fetch = new BidirectionalEntityFetchImpl( this, attributeDefinition, fetchStrategy, join, targetEntityReference );
207+
}
186208
addFetch( fetch );
187209
return fetch;
188210
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,18 @@
3131
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
3232

3333
/**
34-
* Represents a key-many-to-one fetch that is bi-directionally join fetched.
34+
* Represents an entity fetch that is bi-directionally join fetched.
3535
* <p/>
3636
* For example, consider an Order entity whose primary key is partially made up of the Customer entity to which
3737
* it is associated. When we join fetch Customer -> Order(s) and then Order -> Customer we have a bi-directional
3838
* fetch. This class would be used to represent the Order -> Customer part of that link.
3939
*
4040
* @author Steve Ebersole
4141
*/
42-
public class KeyManyToOneBidirectionalEntityFetchImpl extends EntityFetchImpl implements BidirectionalEntityFetch {
42+
public class BidirectionalEntityFetchImpl extends EntityFetchImpl implements BidirectionalEntityFetch {
4343
private final EntityReference targetEntityReference;
4444

45-
public KeyManyToOneBidirectionalEntityFetchImpl(
45+
public BidirectionalEntityFetchImpl(
4646
ExpandingFetchSource fetchSource,
4747
AssociationAttributeDefinition fetchedAttribute,
4848
FetchStrategy fetchStrategy,

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/AbstractLoadPlanBuildingAssociationVisitationStrategy.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -586,11 +586,22 @@ public void foundCircularAssociation(AssociationAttributeDefinition attributeDef
586586

587587
// go ahead and build the bidirectional fetch
588588
if ( attributeDefinition.getAssociationNature() == AssociationAttributeDefinition.AssociationNature.ENTITY ) {
589-
currentSource().buildEntityFetch(
590-
attributeDefinition,
591-
fetchStrategy,
592-
this
593-
);
589+
final Joinable currentEntityPersister = (Joinable) currentSource().resolveEntityReference().getEntityPersister();
590+
final AssociationKey currentEntityReferenceAssociationKey =
591+
new AssociationKey( currentEntityPersister.getTableName(), currentEntityPersister.getKeyColumnNames() );
592+
final Joinable fetchSourceEntityPersister =
593+
(Joinable) registeredFetchSource( attributeDefinition.getAssociationKey() ).resolveEntityReference().getEntityPersister();
594+
final AssociationKey fetchSourceEntityReferenceAssociationKey =
595+
new AssociationKey( fetchSourceEntityPersister.getTableName(), fetchSourceEntityPersister.getKeyColumnNames() );
596+
if ( ! attributeDefinition.getAssociationKey().equals( currentEntityReferenceAssociationKey ) &&
597+
! attributeDefinition.getAssociationKey().equals( fetchSourceEntityReferenceAssociationKey ) ) {
598+
currentSource().buildBidirectionalEntityFetch(
599+
attributeDefinition,
600+
fetchStrategy,
601+
fetchedAssociationKeySourceMap.get( attributeDefinition.getAssociationKey() ).resolveEntityReference(),
602+
this
603+
);
604+
}
594605
}
595606
else {
596607
// Collection

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/spi/ExpandingFetchSource.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424
package org.hibernate.loader.plan2.build.spi;
2525

2626
import org.hibernate.engine.FetchStrategy;
27+
import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
2728
import org.hibernate.loader.plan2.spi.CollectionFetch;
2829
import org.hibernate.loader.plan2.spi.CompositeFetch;
2930
import org.hibernate.loader.plan2.spi.EntityFetch;
31+
import org.hibernate.loader.plan2.spi.EntityReference;
3032
import org.hibernate.loader.plan2.spi.FetchSource;
3133
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
3234
import org.hibernate.persister.walking.spi.AttributeDefinition;
@@ -52,6 +54,12 @@ public EntityFetch buildEntityFetch(
5254
FetchStrategy fetchStrategy,
5355
LoadPlanBuildingContext loadPlanBuildingContext);
5456

57+
public BidirectionalEntityFetch buildBidirectionalEntityFetch(
58+
AssociationAttributeDefinition attributeDefinition,
59+
FetchStrategy fetchStrategy,
60+
EntityReference targetEntityReference,
61+
LoadPlanBuildingContext loadPlanBuildingContext);
62+
5563
public CompositeFetch buildCompositeFetch(
5664
CompositionDefinition attributeDefinition,
5765
LoadPlanBuildingContext loadPlanBuildingContext);

0 commit comments

Comments
 (0)