1010import java .util .Collection ;
1111import java .util .Iterator ;
1212import java .util .List ;
13+ import java .util .Set ;
1314
1415import org .hibernate .HibernateException ;
1516import org .hibernate .bytecode .enhance .spi .interceptor .LazyAttributeLoadingInterceptor ;
1920import org .hibernate .engine .spi .CollectionEntry ;
2021import org .hibernate .engine .spi .EntityEntry ;
2122import org .hibernate .engine .spi .PersistenceContext ;
23+ import org .hibernate .engine .spi .SelfDirtinessTracker ;
2224import org .hibernate .engine .spi .SessionFactoryImplementor ;
2325import org .hibernate .engine .spi .Status ;
2426import org .hibernate .event .spi .DeleteContext ;
2729import org .hibernate .internal .CoreMessageLogger ;
2830import org .hibernate .persister .collection .CollectionPersister ;
2931import org .hibernate .persister .entity .EntityPersister ;
30- import org .hibernate .pretty .MessageHelper ;
31- import org .hibernate .proxy .HibernateProxy ;
3232import org .hibernate .type .AnyType ;
3333import org .hibernate .type .AssociationType ;
3434import org .hibernate .type .CollectionType ;
3838import org .hibernate .type .ForeignKeyDirection ;
3939import org .hibernate .type .ManyToOneType ;
4040import org .hibernate .type .OneToOneType ;
41- import org .hibernate .type .OneToOneType ;
4241import org .hibernate .type .Type ;
4342
43+ import static org .hibernate .engine .internal .ManagedTypeHelper .asManagedEntity ;
44+ import static org .hibernate .engine .internal .ManagedTypeHelper .asSelfDirtinessTrackerOrNull ;
4445import static org .hibernate .engine .internal .ManagedTypeHelper .isHibernateProxy ;
4546import static org .hibernate .engine .spi .CascadingActions .CHECK_ON_FLUSH ;
4647import static org .hibernate .pretty .MessageHelper .infoString ;
47- import static org .hibernate .type .ForeignKeyDirection .TO_PARENT ;
4848
4949/**
5050 * Delegate responsible for, in conjunction with the various
@@ -97,15 +97,29 @@ public static <T> void cascade(
9797 final PersistenceContext persistenceContext = eventSource .getPersistenceContextInternal ();
9898 final boolean enhancedForLazyLoading = persister .getBytecodeEnhancementMetadata ().isEnhancedForLazyLoading ();
9999 final EntityEntry entry ;
100+ final Set <String > dirtyAttributes ;
100101 if ( enhancedForLazyLoading ) {
101102 entry = persistenceContext .getEntry ( parent );
102- if ( entry != null
103- && entry .getLoadedState () == null
104- && entry .getStatus () == Status .MANAGED ) {
105- return ;
103+ if ( entry != null && entry .getLoadedState () == null && entry .getStatus () == Status .MANAGED ) {
104+ final SelfDirtinessTracker selfDirtinessTracker = asSelfDirtinessTrackerOrNull ( parent );
105+ if ( selfDirtinessTracker == null ) {
106+ return ;
107+ }
108+ else {
109+ if ( asManagedEntity ( parent ).$$_hibernate_useTracker () ) {
110+ dirtyAttributes = Set .of ( selfDirtinessTracker .$$_hibernate_getDirtyAttributes () );
111+ }
112+ else {
113+ dirtyAttributes = null ;
114+ }
115+ }
116+ }
117+ else {
118+ dirtyAttributes = null ;
106119 }
107120 }
108121 else {
122+ dirtyAttributes = null ;
109123 entry = null ;
110124 }
111125 final Type [] types = persister .getPropertyTypes ();
@@ -114,8 +128,11 @@ public static <T> void cascade(
114128 final boolean hasUninitializedLazyProperties = persister .hasUninitializedLazyProperties ( parent );
115129
116130 for ( int i = 0 ; i < types .length ; i ++) {
117- final CascadeStyle style = cascadeStyles [ i ];
118131 final String propertyName = propertyNames [ i ];
132+ if ( dirtyAttributes != null && !dirtyAttributes .contains ( propertyName ) ) {
133+ return ;
134+ }
135+ final CascadeStyle style = cascadeStyles [ i ];
119136 final Type type = types [i ];
120137 final boolean isUninitializedProperty =
121138 hasUninitializedLazyProperties &&
0 commit comments