|
12 | 12 | import java.sql.SQLException;
|
13 | 13 | import java.util.ArrayList;
|
14 | 14 | import java.util.Arrays;
|
| 15 | +import java.util.BitSet; |
15 | 16 | import java.util.Collections;
|
16 | 17 | import java.util.Comparator;
|
17 | 18 | import java.util.HashMap;
|
|
67 | 68 | import org.hibernate.engine.jdbc.spi.JdbcServices;
|
68 | 69 | import org.hibernate.engine.spi.CachedNaturalIdValueSource;
|
69 | 70 | import org.hibernate.engine.spi.CascadeStyle;
|
70 |
| -import org.hibernate.engine.spi.CascadingAction; |
71 | 71 | import org.hibernate.engine.spi.CascadingActions;
|
72 | 72 | import org.hibernate.engine.spi.CollectionKey;
|
73 | 73 | import org.hibernate.engine.spi.EntityEntry;
|
|
81 | 81 | import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
82 | 82 | import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
83 | 83 | import org.hibernate.engine.spi.SessionFactoryImplementor;
|
| 84 | +import org.hibernate.engine.spi.SessionImplementor; |
84 | 85 | import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
85 | 86 | import org.hibernate.engine.spi.ValueInclusion;
|
86 | 87 | import org.hibernate.event.spi.EventSource;
|
|
104 | 105 | import org.hibernate.loader.entity.BatchingEntityLoaderBuilder;
|
105 | 106 | import org.hibernate.loader.entity.CacheEntityLoaderHelper;
|
106 | 107 | import org.hibernate.loader.entity.CascadeEntityLoader;
|
107 |
| -import org.hibernate.loader.entity.plan.DynamicBatchingEntityLoaderBuilder; |
108 | 108 | import org.hibernate.loader.entity.EntityLoader;
|
109 | 109 | import org.hibernate.loader.entity.UniqueEntityLoader;
|
110 | 110 | import org.hibernate.loader.entity.plan.MultiEntityLoadingSupport;
|
@@ -2261,6 +2261,52 @@ public int[] resolveAttributeIndexes(String[] attributeNames) {
|
2261 | 2261 | return Arrays.copyOf( fields, counter );
|
2262 | 2262 | }
|
2263 | 2263 |
|
| 2264 | + @Override |
| 2265 | + public int[] resolveDirtyAttributeIndexes( |
| 2266 | + final Object[] currentState, |
| 2267 | + final Object[] previousState, |
| 2268 | + final String[] attributeNames, |
| 2269 | + final SessionImplementor session) { |
| 2270 | + final BitSet mutablePropertiesIndexes = entityMetamodel.getMutablePropertiesIndexes(); |
| 2271 | + final int estimatedSize = attributeNames == null ? 0 : attributeNames.length + mutablePropertiesIndexes.cardinality(); |
| 2272 | + final List<Integer> fields = new ArrayList<>( estimatedSize ); |
| 2273 | + if ( estimatedSize == 0 ) { |
| 2274 | + return ArrayHelper.EMPTY_INT_ARRAY; |
| 2275 | + } |
| 2276 | + if ( !mutablePropertiesIndexes.isEmpty() ) { |
| 2277 | + // We have to check the state for "mutable" properties as dirty tracking isn't aware of mutable types |
| 2278 | + final Type[] propertyTypes = entityMetamodel.getPropertyTypes(); |
| 2279 | + final boolean[] propertyCheckability = entityMetamodel.getPropertyCheckability(); |
| 2280 | + mutablePropertiesIndexes.stream().forEach( i -> { |
| 2281 | + // This is kindly borrowed from org.hibernate.type.TypeHelper.findDirty |
| 2282 | + final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY && |
| 2283 | + ( previousState[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || |
| 2284 | + ( propertyCheckability[i] |
| 2285 | + && propertyTypes[i].isDirty( |
| 2286 | + previousState[i], |
| 2287 | + currentState[i], |
| 2288 | + propertyColumnUpdateable[i], |
| 2289 | + session |
| 2290 | + ) ) ); |
| 2291 | + if ( dirty ) { |
| 2292 | + fields.add( i ); |
| 2293 | + } |
| 2294 | + } ); |
| 2295 | + } |
| 2296 | + |
| 2297 | + if ( attributeNames != null ) { |
| 2298 | + final boolean[] propertyUpdateability = entityMetamodel.getPropertyUpdateability(); |
| 2299 | + for ( String attributeName : attributeNames ) { |
| 2300 | + final Integer index = entityMetamodel.getPropertyIndexOrNull( attributeName ); |
| 2301 | + if ( index != null && propertyUpdateability[index] && !fields.contains( index ) ) { |
| 2302 | + fields.add( index ); |
| 2303 | + } |
| 2304 | + } |
| 2305 | + } |
| 2306 | + |
| 2307 | + return ArrayHelper.toIntArray( fields ); |
| 2308 | + } |
| 2309 | + |
2264 | 2310 | protected String[] getSubclassPropertySubclassNameClosure() {
|
2265 | 2311 | return subclassPropertySubclassNameClosure;
|
2266 | 2312 | }
|
|
0 commit comments