Skip to content

Commit abea1bf

Browse files
committed
HHH-17947 Bidirectional association management shouldn't ignore maintaining inverse lazy objects
1 parent 2b4003c commit abea1bf

File tree

1 file changed

+18
-46
lines changed
  • hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy

1 file changed

+18
-46
lines changed

hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/CodeTemplates.java

Lines changed: 18 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,7 @@ static class CompositeOwnerDirtyCheckingHandler {
357357
static class OneToOneHandler {
358358
@Advice.OnMethodEnter
359359
static void enter(@FieldValue Object field, @Advice.Argument(0) Object argument, @InverseSide boolean inverseSide) {
360-
// Unset the inverse attribute, which possibly initializes the old value,
361-
// only if this is the inverse side, or the old value is already initialized
362-
if ( ( inverseSide || Hibernate.isInitialized( field ) ) && getterSelf() != null ) {
360+
if ( getterSelf() != null ) {
363361
// We copy the old value, then set the field to null which we must do before
364362
// unsetting the inverse attribute, as we'd otherwise run into a stack overflow situation
365363
// The field is writable, so setting it to null here is actually a field write.
@@ -371,9 +369,7 @@ static void enter(@FieldValue Object field, @Advice.Argument(0) Object argument,
371369

372370
@Advice.OnMethodExit
373371
static void exit(@Advice.This Object self, @Advice.Argument(0) Object argument, @InverseSide boolean inverseSide) {
374-
// Update the inverse attribute, which possibly initializes the argument value,
375-
// only if this is the inverse side, or the argument value is already initialized
376-
if ( argument != null && ( inverseSide || Hibernate.isInitialized( argument ) ) && getter( argument ) != self ) {
372+
if ( argument != null && getter( argument ) != self ) {
377373
setterSelf( argument, self );
378374
}
379375
}
@@ -402,13 +398,10 @@ static void setterSelf(Object target, Object argument) {
402398
static class OneToManyOnCollectionHandler {
403399
@Advice.OnMethodEnter
404400
static void enter(@FieldValue Collection<?> field, @Advice.Argument(0) Collection<?> argument, @InverseSide boolean inverseSide) {
405-
// If this is the inverse side or the old collection is already initialized,
406-
// we must unset the respective ManyToOne of the old collection elements,
407-
// because only the owning side is responsible for persisting the state.
408-
if ( ( inverseSide || Hibernate.isInitialized( field ) ) && getterSelf() != null ) {
401+
if ( getterSelf() != null ) {
409402
Object[] array = field.toArray();
410403
for ( int i = 0; i < array.length; i++ ) {
411-
if ( ( inverseSide || Hibernate.isInitialized( array[i] ) ) && ( argument == null || !argument.contains( array[i] ) ) ) {
404+
if ( argument == null || !argument.contains( array[i] ) ) {
412405
setterNull( array[i], null );
413406
}
414407
}
@@ -417,13 +410,10 @@ static void enter(@FieldValue Collection<?> field, @Advice.Argument(0) Collectio
417410

418411
@Advice.OnMethodExit
419412
static void exit(@Advice.This Object self, @Advice.Argument(0) Collection<?> argument, @InverseSide boolean inverseSide) {
420-
// If this is the inverse side or the new collection is already initialized,
421-
// we must set the respective ManyToOne on the new collection elements,
422-
// because only the owning side is responsible for persisting the state.
423-
if ( argument != null && ( inverseSide || Hibernate.isInitialized( argument ) ) ) {
413+
if ( argument != null ) {
424414
Object[] array = argument.toArray();
425415
for ( int i = 0; i < array.length; i++ ) {
426-
if ( ( inverseSide || Hibernate.isInitialized( array[i] ) ) && getter( array[i] ) != self ) {
416+
if ( getter( array[i] ) != self ) {
427417
setterSelf( array[i], self );
428418
}
429419
}
@@ -454,14 +444,10 @@ static void setterSelf(Object target, Object argument) {
454444
static class OneToManyOnMapHandler {
455445
@Advice.OnMethodEnter
456446
static void enter(@FieldValue Map<?, ?> field, @Advice.Argument(0) Map<?, ?> argument, @InverseSide boolean inverseSide) {
457-
// If this is the inverse side or the old collection is already initialized,
458-
// we must unset the respective ManyToOne of the old collection elements,
459-
// because only the owning side is responsible for persisting the state.
460-
if ( ( inverseSide || Hibernate.isInitialized( field ) ) && getterSelf() != null ) {
447+
if ( getterSelf() != null ) {
461448
Object[] array = field.values().toArray();
462449
for ( int i = 0; i < array.length; i++ ) {
463-
if ( ( inverseSide || Hibernate.isInitialized( array[i] ) )
464-
&& ( argument == null || !argument.containsValue( array[i] ) ) ) {
450+
if ( argument == null || !argument.containsValue( array[i] ) ) {
465451
setterNull( array[i], null );
466452
}
467453
}
@@ -470,13 +456,10 @@ static void enter(@FieldValue Map<?, ?> field, @Advice.Argument(0) Map<?, ?> arg
470456

471457
@Advice.OnMethodExit
472458
static void exit(@Advice.This Object self, @Advice.Argument(0) Map<?, ?> argument, @InverseSide boolean inverseSide) {
473-
// If this is the inverse side or the new collection is already initialized,
474-
// we must set the respective ManyToOne on the new collection elements,
475-
// because only the owning side is responsible for persisting the state.
476-
if ( argument != null && ( inverseSide || Hibernate.isInitialized( argument ) ) ) {
459+
if ( argument != null ) {
477460
Object[] array = argument.values().toArray();
478461
for ( int i = 0; i < array.length; i++ ) {
479-
if ( ( inverseSide || Hibernate.isInitialized( array[i] ) ) && getter( array[i] ) != self ) {
462+
if ( getter( array[i] ) != self ) {
480463
setterSelf( array[i], self );
481464
}
482465
}
@@ -507,8 +490,7 @@ static void setterSelf(Object target, Object argument) {
507490
static class ManyToOneHandler {
508491
@Advice.OnMethodEnter
509492
static void enter(@Advice.This Object self, @FieldValue Object field, @BidirectionalAttribute String inverseAttribute) {
510-
// This is always the owning side, so we only need to update the inverse side if the collection is initialized
511-
if ( getterSelf() != null && Hibernate.isPropertyInitialized( field, inverseAttribute ) ) {
493+
if ( getterSelf() != null ) {
512494
Collection<?> c = getter( field );
513495
if ( c != null ) {
514496
c.remove( self );
@@ -518,8 +500,7 @@ static void enter(@Advice.This Object self, @FieldValue Object field, @Bidirecti
518500

519501
@Advice.OnMethodExit
520502
static void exit(@Advice.This Object self, @Advice.Argument(0) Object argument, @BidirectionalAttribute String inverseAttribute) {
521-
// This is always the owning side, so we only need to update the inverse side if the collection is initialized
522-
if ( argument != null && Hibernate.isPropertyInitialized( argument, inverseAttribute ) ) {
503+
if ( argument != null ) {
523504
Collection<Object> c = getter( argument );
524505
if ( c != null && !c.contains( self ) ) {
525506
c.add( self );
@@ -541,14 +522,10 @@ static Object getterSelf() {
541522
static class ManyToManyHandler {
542523
@Advice.OnMethodEnter
543524
static void enter(@Advice.This Object self, @FieldValue Collection<?> field, @Advice.Argument(0) Collection<?> argument, @InverseSide boolean inverseSide, @BidirectionalAttribute String bidirectionalAttribute) {
544-
// If this is the inverse side or the old collection is already initialized,
545-
// we must remove self from the respective old collection elements inverse collections,
546-
// because only the owning side is responsible for persisting the state.
547-
if ( ( inverseSide || Hibernate.isInitialized( field ) ) && getterSelf() != null ) {
525+
if ( getterSelf() != null ) {
548526
Object[] array = field.toArray();
549527
for ( int i = 0; i < array.length; i++ ) {
550-
if ( ( inverseSide || Hibernate.isPropertyInitialized( array[i], bidirectionalAttribute ) )
551-
&& ( argument == null || !argument.contains( array[i] ) ) ) {
528+
if ( argument == null || !argument.contains( array[i] ) ) {
552529
getter( array[i] ).remove( self );
553530
}
554531
}
@@ -557,17 +534,12 @@ static void enter(@Advice.This Object self, @FieldValue Collection<?> field, @Ad
557534

558535
@Advice.OnMethodExit
559536
static void exit(@Advice.This Object self, @Advice.Argument(0) Collection<?> argument, @InverseSide boolean inverseSide, @BidirectionalAttribute String bidirectionalAttribute) {
560-
// If this is the inverse side or the new collection is already initialized,
561-
// we must add self to the respective new collection elements inverse collections,
562-
// because only the owning side is responsible for persisting the state.
563-
if ( argument != null && ( inverseSide || Hibernate.isInitialized( argument ) ) ) {
537+
if ( argument != null ) {
564538
Object[] array = argument.toArray();
565539
for ( Object array1 : array ) {
566-
if ( inverseSide || Hibernate.isPropertyInitialized( array1, bidirectionalAttribute ) ) {
567-
Collection<Object> c = getter( array1 );
568-
if ( c != null && !c.contains( self ) ) {
569-
c.add( self );
570-
}
540+
Collection<Object> c = getter( array1 );
541+
if ( c != null && !c.contains( self ) ) {
542+
c.add( self );
571543
}
572544
}
573545
}

0 commit comments

Comments
 (0)