Skip to content

Commit b735b61

Browse files
committed
HHH-19394 add an optimization to short-circuit cascade PERSIST
1 parent 6a1adee commit b735b61

File tree

7 files changed

+90
-10
lines changed

7 files changed

+90
-10
lines changed

hibernate-core/src/main/java/org/hibernate/engine/spi/CascadingActions.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ public boolean performOnLazyProperty() {
283283
return false;
284284
}
285285

286+
@Override
287+
public boolean anythingToCascade(EntityPersister persister) {
288+
return persister.hasCascadePersist();
289+
}
290+
286291
@Override
287292
public String toString() {
288293
return "ACTION_PERSIST";
@@ -326,6 +331,11 @@ public boolean performOnLazyProperty() {
326331
return false;
327332
}
328333

334+
@Override
335+
public boolean anythingToCascade(EntityPersister persister) {
336+
return persister.hasCascadePersist();
337+
}
338+
329339
@Override
330340
public String toString() {
331341
return "ACTION_PERSIST_ON_FLUSH";
@@ -380,13 +390,19 @@ public Iterator<?> getCascadableChildrenIterator(
380390

381391
@Override
382392
public boolean anythingToCascade(EntityPersister persister) {
393+
// Must override the implementation from the superclass
394+
// because transient checking happens even for entities
395+
// with cascade NONE on all associations
383396
// if the entity has no associations, we can just ignore it
384397
return persister.hasToOnes()
385398
|| persister.hasOwnedCollections();
386399
}
387400

388401
@Override
389402
public boolean appliesTo(Type type, CascadeStyle style) {
403+
// Very important to override the implementation from
404+
// the superclass, because CHECK_ON_FLUSH is the only
405+
// style that executes for fields with cascade NONE
390406
return super.appliesTo( type, style )
391407
// we only care about associations here,
392408
// but they can hide inside embeddables

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3750,6 +3750,11 @@ public boolean hasToOnes() {
37503750
return entityMetamodel.hasToOnes();
37513751
}
37523752

3753+
@Override
3754+
public boolean hasCascadePersist() {
3755+
return entityMetamodel.hasCascadePersist();
3756+
}
3757+
37533758
@Override
37543759
public boolean hasCascadeDelete() {
37553760
return entityMetamodel.hasCascadeDelete();

hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -337,24 +337,30 @@ default void visitQuerySpaces(Consumer<String> querySpaceConsumer) {
337337

338338
/**
339339
* Determine whether this entity has any
340-
* (non-{@linkplain org.hibernate.engine.spi.CascadeStyles#NONE none}) cascading.
340+
* {@linkplain org.hibernate.engine.spi.CascadeStyles#NONE cascading} operations.
341341
*
342342
* @return True if the entity has any properties with a cascade other than NONE;
343343
* false otherwise (aka, no cascading).
344344
*/
345345
boolean hasCascades();
346346

347+
/**
348+
* Determine whether this entity has any
349+
* {@linkplain org.hibernate.engine.spi.CascadeStyles#PERSIST persist cascading}.
350+
*
351+
* @return True if the entity has any properties with a cascade PERSIST or ALL;
352+
* false otherwise.
353+
*/
354+
boolean hasCascadePersist();
355+
347356
/**
348357
* Determine whether this entity has any
349358
* {@linkplain org.hibernate.engine.spi.CascadeStyles#DELETE delete cascading}.
350359
*
351-
* @return True if the entity has any properties with a cascade other than NONE;
360+
* @return True if the entity has any properties with a cascade REMOVE or ALL;
352361
* false otherwise.
353362
*/
354-
default boolean hasCascadeDelete() {
355-
//bad default implementation for compatibility
356-
return hasCascades();
357-
}
363+
boolean hasCascadeDelete();
358364

359365
/**
360366
* Determine whether this entity has any many-to-one or one-to-one associations.
@@ -372,10 +378,7 @@ default boolean hasCascadeDelete() {
372378
* @return True if the entity has an owned collection;
373379
* false otherwise.
374380
*/
375-
default boolean hasOwnedCollections() {
376-
//bad default implementation for compatibility
377-
return hasCollections();
378-
}
381+
boolean hasOwnedCollections();
379382

380383
/**
381384
* Determine whether instances of this entity are considered mutable.

hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ public class EntityMetamodel implements Serializable {
128128
private boolean lazy; //not final because proxy factory creation can fail
129129
private final boolean hasCascades;
130130
private final boolean hasToOnes;
131+
private final boolean hasCascadePersist;
131132
private final boolean hasCascadeDelete;
132133
private final boolean mutable;
133134
private final boolean isAbstract;
@@ -242,6 +243,7 @@ public EntityMetamodel(
242243
int tempVersionProperty = NO_VERSION_INDX;
243244
boolean foundCascade = false;
244245
boolean foundToOne = false;
246+
boolean foundCascadePersist = false;
245247
boolean foundCascadeDelete = false;
246248
boolean foundCollection = false;
247249
boolean foundOwnedCollection = false;
@@ -378,6 +380,10 @@ else if ( !allowMutation ) {
378380
if ( cascadeStyles[i] != CascadeStyles.NONE ) {
379381
foundCascade = true;
380382
}
383+
if ( cascadeStyles[i].doCascade(CascadingActions.PERSIST)
384+
|| cascadeStyles[i].doCascade(CascadingActions.PERSIST_ON_FLUSH) ) {
385+
foundCascadePersist = true;
386+
}
381387
if ( cascadeStyles[i].doCascade(CascadingActions.REMOVE) ) {
382388
foundCascadeDelete = true;
383389
}
@@ -420,6 +426,7 @@ else if ( !allowMutation ) {
420426

421427
hasCascades = foundCascade;
422428
hasToOnes = foundToOne;
429+
hasCascadePersist = foundCascadePersist;
423430
hasCascadeDelete = foundCascadeDelete;
424431
hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;
425432
versionPropertyIndex = tempVersionProperty;
@@ -768,6 +775,10 @@ public boolean hasCascadeDelete() {
768775
return hasCascadeDelete;
769776
}
770777

778+
public boolean hasCascadePersist() {
779+
return hasCascadePersist;
780+
}
781+
771782
public boolean isMutable() {
772783
return mutable;
773784
}

hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,26 @@ public boolean hasCascades() {
304304
return false;
305305
}
306306

307+
@Override
308+
public boolean hasCascadeDelete() {
309+
return false;
310+
}
311+
307312
@Override
308313
public boolean hasToOnes() {
309314
return false;
310315
}
311316

317+
@Override
318+
public boolean hasCascadePersist() {
319+
return false;
320+
}
321+
322+
@Override
323+
public boolean hasOwnedCollections() {
324+
return false;
325+
}
326+
312327
@Override
313328
public boolean isMutable() {
314329
return false;

hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,26 @@ public boolean hasCascades() {
329329
return false;
330330
}
331331

332+
@Override
333+
public boolean hasCascadeDelete() {
334+
return false;
335+
}
336+
332337
@Override
333338
public boolean hasToOnes() {
334339
return false;
335340
}
336341

342+
@Override
343+
public boolean hasCascadePersist() {
344+
return false;
345+
}
346+
347+
@Override
348+
public boolean hasOwnedCollections() {
349+
return false;
350+
}
351+
337352
@Override
338353
public boolean isMutable() {
339354
return false;

hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,26 @@ public boolean hasCascades() {
257257
return false;
258258
}
259259

260+
@Override
261+
public boolean hasCascadeDelete() {
262+
return false;
263+
}
264+
260265
@Override
261266
public boolean hasToOnes() {
262267
return false;
263268
}
264269

270+
@Override
271+
public boolean hasCascadePersist() {
272+
return false;
273+
}
274+
275+
@Override
276+
public boolean hasOwnedCollections() {
277+
return false;
278+
}
279+
265280
public boolean isMutable() {
266281
return true;
267282
}

0 commit comments

Comments
 (0)