Skip to content

Commit e1105fb

Browse files
committed
HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)
1 parent f32c736 commit e1105fb

File tree

9 files changed

+83
-19
lines changed

9 files changed

+83
-19
lines changed

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/spaces/CollectionQuerySpaceImpl.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ public CollectionQuerySpaceImpl(
4444
CollectionPersister persister,
4545
String uid,
4646
QuerySpacesImpl querySpaces,
47+
boolean canJoinsBeRequired,
4748
SessionFactoryImplementor sessionFactory) {
48-
super( uid, Disposition.COLLECTION, querySpaces, sessionFactory );
49+
super( uid, Disposition.COLLECTION, querySpaces, canJoinsBeRequired, sessionFactory );
4950
this.persister = persister;
5051
}
5152

@@ -62,11 +63,13 @@ public PropertyMapping getPropertyMapping() {
6263
public JoinImpl addIndexEntityJoin(
6364
final EntityPersister indexPersister,
6465
LoadPlanBuildingContext context) {
66+
final boolean required = canJoinsBeRequired();
6567
final String entityQuerySpaceUid = getQuerySpaces().generateImplicitUid();
6668
final EntityQuerySpaceImpl entityQuerySpace = new EntityQuerySpaceImpl(
6769
indexPersister,
6870
entityQuerySpaceUid,
6971
getQuerySpaces(),
72+
required,
7073
sessionFactory()
7174
);
7275
getQuerySpaces().registerQuerySpace( entityQuerySpace );
@@ -77,7 +80,7 @@ public JoinImpl addIndexEntityJoin(
7780
entityQuerySpace,
7881
// not sure this 'rhsColumnNames' bit is correct...
7982
( (Queryable) indexPersister ).getKeyColumnNames(),
80-
false
83+
required
8184
);
8285
internalGetJoins().add( join );
8386

@@ -96,6 +99,7 @@ public JoinImpl addIndexCompositeJoin(
9699
),
97100
compositeQuerySpaceUid,
98101
getQuerySpaces(),
102+
canJoinsBeRequired(),
99103
sessionFactory()
100104
);
101105
getQuerySpaces().registerQuerySpace( compositeQuerySpace );
@@ -105,7 +109,7 @@ public JoinImpl addIndexCompositeJoin(
105109
"index",
106110
compositeQuerySpace,
107111
null,
108-
false
112+
canJoinsBeRequired()
109113
);
110114
internalGetJoins().add( join );
111115

@@ -120,6 +124,7 @@ public JoinImpl addElementEntityJoin(
120124
elementPersister,
121125
entityQuerySpaceUid,
122126
getQuerySpaces(),
127+
canJoinsBeRequired(),
123128
sessionFactory()
124129
);
125130
( (QuerySpacesImpl) context.getQuerySpaces() ).registerQuerySpace( entityQuerySpace );
@@ -130,7 +135,7 @@ public JoinImpl addElementEntityJoin(
130135
"id",
131136
entityQuerySpace,
132137
( (Queryable) elementPersister ).getKeyColumnNames(),
133-
false
138+
canJoinsBeRequired()
134139
);
135140
internalGetJoins().add( join );
136141

@@ -150,6 +155,7 @@ public Join addElementCompositeJoin(
150155
),
151156
compositeQuerySpaceUid,
152157
getQuerySpaces(),
158+
canJoinsBeRequired(),
153159
sessionFactory()
154160
);
155161
( (QuerySpacesImpl) context.getQuerySpaces() ).registerQuerySpace( compositeQuerySpace );
@@ -160,7 +166,7 @@ public Join addElementCompositeJoin(
160166
"elements",
161167
compositeQuerySpace,
162168
null,
163-
false
169+
canJoinsBeRequired()
164170
);
165171
internalGetJoins().add( join );
166172

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/spaces/CompositeQuerySpaceImpl.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,23 @@ public CompositeQuerySpaceImpl(
4545
CompositePropertyMapping compositeSubPropertyMapping,
4646
String uid,
4747
QuerySpacesImpl querySpaces,
48+
boolean canJoinsBeRequired,
4849
SessionFactoryImplementor sessionFactory) {
49-
super( uid, Disposition.COMPOSITE, querySpaces, sessionFactory );
50+
super( uid, Disposition.COMPOSITE, querySpaces, canJoinsBeRequired, sessionFactory );
5051
this.compositeSubPropertyMapping = compositeSubPropertyMapping;
5152
}
5253

5354
public CompositeQuerySpaceImpl(
5455
EntityQuerySpaceImpl entityQuerySpace,
5556
CompositePropertyMapping compositePropertyMapping,
56-
String uid) {
57+
String uid,
58+
boolean canJoinsBeRequired) {
5759
// todo : we may need to keep around the owning entity query space to be able to properly handle circularity...
5860
this(
5961
compositePropertyMapping,
6062
uid,
6163
entityQuerySpace.getQuerySpaces(),
64+
canJoinsBeRequired,
6265
entityQuerySpace.sessionFactory()
6366
);
6467
}
@@ -71,11 +74,13 @@ public PropertyMapping getPropertyMapping() {
7174
@Override
7275
public JoinImpl addCompositeJoin(CompositionDefinition compositionDefinition, String querySpaceUid) {
7376
final String propertyPath = compositionDefinition.getName();
77+
final boolean required = canJoinsBeRequired() && !compositionDefinition.isNullable();
7478

7579
final CompositeQuerySpaceImpl rhs = new CompositeQuerySpaceImpl(
7680
compositeSubPropertyMapping,
7781
querySpaceUid,
7882
getQuerySpaces(),
83+
required,
7984
sessionFactory()
8085
);
8186
getQuerySpaces().registerQuerySpace( rhs );
@@ -85,7 +90,7 @@ public JoinImpl addCompositeJoin(CompositionDefinition compositionDefinition, St
8590
propertyPath,
8691
rhs,
8792
null,
88-
compositionDefinition.isNullable()
93+
required
8994
);
9095
internalGetJoins().add( join );
9196

@@ -98,10 +103,13 @@ public JoinImpl addEntityJoin(
98103
EntityPersister persister,
99104
String querySpaceUid,
100105
boolean optional) {
106+
final boolean required = canJoinsBeRequired() && !optional;
107+
101108
final EntityQuerySpaceImpl rhs = new EntityQuerySpaceImpl(
102109
persister,
103110
querySpaceUid,
104111
getQuerySpaces(),
112+
required,
105113
sessionFactory()
106114
);
107115
getQuerySpaces().registerQuerySpace( rhs );
@@ -115,7 +123,7 @@ public JoinImpl addEntityJoin(
115123
(EntityType) attributeDefinition.getType(),
116124
sessionFactory()
117125
),
118-
optional
126+
required
119127
);
120128
internalGetJoins().add( join );
121129

@@ -127,10 +135,13 @@ public JoinImpl addCollectionJoin(
127135
AttributeDefinition attributeDefinition,
128136
CollectionPersister collectionPersister,
129137
String querySpaceUid) {
138+
final boolean required = canJoinsBeRequired() && ! attributeDefinition.isNullable();
139+
130140
final CollectionQuerySpaceImpl rhs = new CollectionQuerySpaceImpl(
131141
collectionPersister,
132142
querySpaceUid,
133143
getQuerySpaces(),
144+
required,
134145
sessionFactory()
135146
);
136147
getQuerySpaces().registerQuerySpace( rhs );
@@ -140,7 +151,7 @@ public JoinImpl addCollectionJoin(
140151
attributeDefinition.getName(),
141152
rhs,
142153
( (CollectionType) attributeDefinition.getType() ).getAssociatedJoinable( sessionFactory() ).getKeyColumnNames(),
143-
attributeDefinition.isNullable()
154+
required
144155
);
145156
internalGetJoins().add( join );
146157

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/spaces/EntityQuerySpaceImpl.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ public EntityQuerySpaceImpl(
4747
EntityPersister persister,
4848
String uid,
4949
QuerySpacesImpl querySpaces,
50+
boolean canJoinsBeRequired,
5051
SessionFactoryImplementor sessionFactory) {
51-
super( uid, Disposition.ENTITY, querySpaces, sessionFactory );
52+
super( uid, Disposition.ENTITY, querySpaces, canJoinsBeRequired, sessionFactory );
5253
this.persister = persister;
5354
}
5455

@@ -71,6 +72,8 @@ public EntityPersister getEntityPersister() {
7172

7273
@Override
7374
public JoinImpl addCompositeJoin(CompositionDefinition compositionDefinition, String querySpaceUid) {
75+
final boolean required = canJoinsBeRequired() && !compositionDefinition.isNullable();
76+
7477
final CompositeQuerySpaceImpl rhs = new CompositeQuerySpaceImpl(
7578
new CompositePropertyMapping(
7679
compositionDefinition.getType(),
@@ -79,6 +82,7 @@ public JoinImpl addCompositeJoin(CompositionDefinition compositionDefinition, St
7982
),
8083
querySpaceUid,
8184
getQuerySpaces(),
85+
required,
8286
sessionFactory()
8387
);
8488
getQuerySpaces().registerQuerySpace( rhs );
@@ -88,7 +92,7 @@ public JoinImpl addCompositeJoin(CompositionDefinition compositionDefinition, St
8892
compositionDefinition.getName(),
8993
rhs,
9094
null,
91-
compositionDefinition.isNullable()
95+
required
9296
);
9397
internalGetJoins().add( join );
9498

@@ -100,10 +104,13 @@ public JoinImpl addEntityJoin(
100104
EntityPersister persister,
101105
String querySpaceUid,
102106
boolean optional) {
107+
final boolean required = canJoinsBeRequired() && !optional;
108+
103109
final EntityQuerySpaceImpl rhs = new EntityQuerySpaceImpl(
104110
persister,
105111
querySpaceUid,
106112
getQuerySpaces(),
113+
required,
107114
sessionFactory()
108115
);
109116
getQuerySpaces().registerQuerySpace( rhs );
@@ -116,7 +123,7 @@ public JoinImpl addEntityJoin(
116123
(EntityType) attribute.getType(),
117124
sessionFactory()
118125
),
119-
optional
126+
required
120127
);
121128
internalGetJoins().add( join );
122129

@@ -128,10 +135,13 @@ public JoinImpl addCollectionJoin(
128135
AttributeDefinition attributeDefinition,
129136
CollectionPersister collectionPersister,
130137
String querySpaceUid) {
138+
final boolean required = canJoinsBeRequired() && !attributeDefinition.isNullable();
139+
131140
final CollectionQuerySpaceImpl rhs = new CollectionQuerySpaceImpl(
132141
collectionPersister,
133142
querySpaceUid,
134143
getQuerySpaces(),
144+
required,
135145
sessionFactory()
136146
);
137147
getQuerySpaces().registerQuerySpace( rhs );
@@ -141,7 +151,7 @@ public JoinImpl addCollectionJoin(
141151
attributeDefinition.getName(),
142152
rhs,
143153
( (CollectionType) attributeDefinition.getType() ).getAssociatedJoinable( sessionFactory() ).getKeyColumnNames(),
144-
attributeDefinition.isNullable()
154+
required
145155
);
146156
internalGetJoins().add( join );
147157

@@ -158,7 +168,8 @@ public Join makeCompositeIdentifierJoin() {
158168
(PropertyMapping) getEntityPersister(),
159169
getEntityPersister().getIdentifierPropertyName()
160170
),
161-
compositeQuerySpaceUid
171+
compositeQuerySpaceUid,
172+
canJoinsBeRequired()
162173
);
163174
getQuerySpaces().registerQuerySpace( rhs );
164175

@@ -167,7 +178,7 @@ public Join makeCompositeIdentifierJoin() {
167178
"id",
168179
rhs,
169180
null,
170-
false
181+
canJoinsBeRequired()
171182
);
172183
internalGetJoins().add( join );
173184

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/spaces/JoinImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public QuerySpace getRightHandSide() {
6969
}
7070

7171
@Override
72-
public boolean isRightHandSideOptional() {
72+
public boolean isRightHandSideRequired() {
7373
return rightHandSideOptional;
7474
}
7575

hibernate-core/src/main/java/org/hibernate/loader/plan2/build/internal/spaces/QuerySpacesImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public EntityQuerySpace makeEntityQuerySpace(String uid, EntityPersister entityP
9595
entityPersister,
9696
uid,
9797
this,
98+
true,
9899
sessionFactory
99100
);
100101
registerQuerySpace( space );
@@ -113,6 +114,7 @@ public CollectionQuerySpaceImpl makeCollectionQuerySpace(String uid, CollectionP
113114
collectionPersister,
114115
uid,
115116
this,
117+
true,
116118
sessionFactory
117119
);
118120
registerQuerySpace( space );

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,21 @@ public abstract class AbstractQuerySpace extends AbstractPlanNode implements Que
4242
private final String uid;
4343
private final Disposition disposition;
4444
private final QuerySpacesImpl querySpaces;
45+
private final boolean canJoinsBeRequired;
4546

4647
private List<Join> joins;
4748

4849
public AbstractQuerySpace(
4950
String uid,
5051
Disposition disposition,
5152
QuerySpacesImpl querySpaces,
53+
boolean canJoinsBeRequired,
5254
SessionFactoryImplementor sessionFactory) {
5355
super( sessionFactory );
5456
this.uid = uid;
5557
this.disposition = disposition;
5658
this.querySpaces = querySpaces;
59+
this.canJoinsBeRequired = canJoinsBeRequired;
5760
}
5861

5962
protected SessionFactoryImplementor sessionFactory() {
@@ -63,6 +66,15 @@ protected SessionFactoryImplementor sessionFactory() {
6366
// todo : copy ctor - that depends how graph copying works here...
6467

6568

69+
/**
70+
* Can any joins created from here (with this as the left-hand side) be required joins?
71+
*
72+
* @return {@code true} indicates joins can be required; {@code false} indicates they cannot.
73+
*/
74+
public boolean canJoinsBeRequired() {
75+
return canJoinsBeRequired;
76+
}
77+
6678
/**
6779
* Provides subclasses access to the spaces to which this space belongs.
6880
*

hibernate-core/src/main/java/org/hibernate/loader/plan2/exec/internal/LoadQueryJoinAndFetchProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ private void renderEntityJoin(Join join, JoinFragment joinFragment) {
179179
addJoins(
180180
joinFragment,
181181
joinable,
182-
join.isRightHandSideOptional() ? JoinType.LEFT_OUTER_JOIN : JoinType.INNER_JOIN,
182+
join.isRightHandSideRequired() ? JoinType.INNER_JOIN : JoinType.LEFT_OUTER_JOIN,
183183
aliases.getTableAlias(),
184184
rhsColumnNames,
185185
aliasedLhsColumnNames,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public interface Join {
4040

4141
public QuerySpace getRightHandSide();
4242

43-
public boolean isRightHandSideOptional();
43+
public boolean isRightHandSideRequired();
4444

4545
// Ugh! This part will unfortunately be SQL specific :( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4646

hibernate-core/src/test/java/org/hibernate/test/loadplans/plans/LoadPlanStructureAssertionTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525

2626
import org.hibernate.cfg.Configuration;
2727
import org.hibernate.engine.spi.SessionFactoryImplementor;
28+
29+
import org.hibernate.test.annotations.Country;
30+
import org.hibernate.test.annotations.collectionelement.Boy;
31+
import org.hibernate.test.annotations.collectionelement.Matrix;
32+
import org.hibernate.test.annotations.collectionelement.TestCourse;
2833
import org.hibernate.test.loadplans.process.EncapsulatedCompositeIdResultSetProcessorTest;
2934

3035
//import org.hibernate.loader.plan2.spi.BidirectionalEntityFetch;
@@ -255,6 +260,23 @@ public void testManyToMany() {
255260

256261
}
257262

263+
@Test
264+
public void testAnotherBasicCollection() {
265+
Configuration cfg = new Configuration();
266+
cfg.addAnnotatedClass( Boy.class );
267+
cfg.addAnnotatedClass( Country.class );
268+
cfg.addAnnotatedClass( TestCourse.class );
269+
cfg.addAnnotatedClass( Matrix.class );
270+
SessionFactoryImplementor sf = (SessionFactoryImplementor) cfg.buildSessionFactory();
271+
272+
try {
273+
doCompare( sf, (OuterJoinLoadable) sf.getClassMetadata( Boy.class ) );
274+
}
275+
finally {
276+
sf.close();
277+
}
278+
}
279+
258280
private void doCompare(SessionFactoryImplementor sf, OuterJoinLoadable persister) {
259281
LoadPlanStructureAssertionHelper.INSTANCE.performBasicComparison( sf, persister );
260282
}

0 commit comments

Comments
 (0)