HHH-11506 - Fix update of lazy attributes when there are attributes not loaded

HHH-11506 - Deprecate methods

HHH-11506 : Added original TypeHelper#findModfied and deprecated; changed deprecated methods to call the new methods.

(cherry picked from commit aaebcdf454)
This commit is contained in:
barreiro 2017-03-08 17:10:28 +00:00 committed by Gail Badner
parent 3b754886f1
commit a9022e5b04
5 changed files with 77 additions and 9 deletions

View File

@ -4206,7 +4206,6 @@ public abstract class AbstractEntityPersister
currentState, currentState,
previousState, previousState,
propertyColumnUpdateable, propertyColumnUpdateable,
hasUninitializedLazyProperties( entity ),
session session
); );
if ( props == null ) { if ( props == null ) {
@ -4237,7 +4236,6 @@ public abstract class AbstractEntityPersister
current, current,
old, old,
propertyColumnUpdateable, propertyColumnUpdateable,
hasUninitializedLazyProperties( entity ),
session session
); );
if ( props == null ) { if ( props == null ) {

View File

@ -86,7 +86,7 @@ public abstract class AbstractNonIdentifierAttribute extends AbstractAttribute i
@Override @Override
public boolean isDirtyCheckable(boolean hasUninitializedProperties) { public boolean isDirtyCheckable(boolean hasUninitializedProperties) {
return isDirtyCheckable() && ( !hasUninitializedProperties || !isLazy() ); return isDirtyCheckable();
} }
@Override @Override

View File

@ -24,6 +24,10 @@ public interface NonIdentifierAttribute extends Attribute, AttributeDefinition {
public boolean isNullable(); public boolean isNullable();
/**
* @deprecated Use {@link org.hibernate.tuple.NonIdentifierAttribute#isDirtyCheckable()} instead
*/
@Deprecated
public boolean isDirtyCheckable(boolean hasUninitializedProperties); public boolean isDirtyCheckable(boolean hasUninitializedProperties);
public boolean isDirtyCheckable(); public boolean isDirtyCheckable();

View File

@ -278,7 +278,10 @@ public class TypeHelper {
* @param session The session from which the dirty check request originated. * @param session The session from which the dirty check request originated.
* *
* @return Array containing indices of the dirty properties, or null if no properties considered dirty. * @return Array containing indices of the dirty properties, or null if no properties considered dirty.
*
* @deprecated Use {org.hibernate.type.TypeHelper{@link #findDirty(NonIdentifierAttribute[], Object[], Object[], boolean[][], SessionImplementor)} instead
*/ */
@Deprecated
public static int[] findDirty( public static int[] findDirty(
final NonIdentifierAttribute[] properties, final NonIdentifierAttribute[] properties,
final Object[] currentState, final Object[] currentState,
@ -286,13 +289,36 @@ public class TypeHelper {
final boolean[][] includeColumns, final boolean[][] includeColumns,
final boolean anyUninitializedProperties, final boolean anyUninitializedProperties,
final SessionImplementor session) { final SessionImplementor session) {
return findDirty( properties, currentState, previousState, includeColumns, session );
}
/**
* Determine if any of the given field values are dirty, returning an array containing
* indices of the dirty fields.
* <p/>
* If it is determined that no fields are dirty, null is returned.
*
* @param properties The property definitions
* @param currentState The current state of the entity
* @param previousState The baseline state of the entity
* @param includeColumns Columns to be included in the dirty checking, per property
* @param session The session from which the dirty check request originated.
*
* @return Array containing indices of the dirty properties, or null if no properties considered dirty.
*/
public static int[] findDirty(
final NonIdentifierAttribute[] properties,
final Object[] currentState,
final Object[] previousState,
final boolean[][] includeColumns,
final SessionImplementor session) {
int[] results = null; int[] results = null;
int count = 0; int count = 0;
int span = properties.length; int span = properties.length;
for ( int i = 0; i < span; i++ ) { for ( int i = 0; i < span; i++ ) {
final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY
&& properties[i].isDirtyCheckable( anyUninitializedProperties ) && properties[i].isDirtyCheckable()
&& properties[i].getType().isDirty( previousState[i], currentState[i], includeColumns[i], session ); && properties[i].getType().isDirty( previousState[i], currentState[i], includeColumns[i], session );
if ( dirty ) { if ( dirty ) {
if ( results == null ) { if ( results == null ) {
@ -326,7 +352,11 @@ public class TypeHelper {
* @param session The session from which the dirty check request originated. * @param session The session from which the dirty check request originated.
* *
* @return Array containing indices of the modified properties, or null if no properties considered modified. * @return Array containing indices of the modified properties, or null if no properties considered modified.
*
* @deprecated Use {@link #findModified(NonIdentifierAttribute[], Object[], Object[], boolean[][], boolean, SessionImplementor)}
* instead.
*/ */
@Deprecated
public static int[] findModified( public static int[] findModified(
final NonIdentifierAttribute[] properties, final NonIdentifierAttribute[] properties,
final Object[] currentState, final Object[] currentState,
@ -334,15 +364,37 @@ public class TypeHelper {
final boolean[][] includeColumns, final boolean[][] includeColumns,
final boolean anyUninitializedProperties, final boolean anyUninitializedProperties,
final SessionImplementor session) { final SessionImplementor session) {
return findModified( properties, currentState, previousState, includeColumns, session );
}
/**
* Determine if any of the given field values are modified, returning an array containing
* indices of the modified fields.
* <p/>
* If it is determined that no fields are dirty, null is returned.
*
* @param properties The property definitions
* @param currentState The current state of the entity
* @param previousState The baseline state of the entity
* @param includeColumns Columns to be included in the mod checking, per property
* @param session The session from which the dirty check request originated.
*
* @return Array containing indices of the modified properties, or null if no properties considered modified.
**/
public static int[] findModified(
final NonIdentifierAttribute[] properties,
final Object[] currentState,
final Object[] previousState,
final boolean[][] includeColumns,
final SessionImplementor session) {
int[] results = null; int[] results = null;
int count = 0; int count = 0;
int span = properties.length; int span = properties.length;
for ( int i = 0; i < span; i++ ) { for ( int i = 0; i < span; i++ ) {
final boolean modified = currentState[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY final boolean modified = currentState[ i ] != LazyPropertyInitializer.UNFETCHED_PROPERTY
&& properties[i].isDirtyCheckable(anyUninitializedProperties) && properties[ i ].isDirtyCheckable()
&& properties[i].getType().isModified( previousState[i], currentState[i], includeColumns[i], session ); && properties[ i ].getType().isModified( previousState[ i ], currentState[ i ], includeColumns[ i ], session );
if ( modified ) { if ( modified ) {
if ( results == null ) { if ( results == null ) {
results = new int[span]; results = new int[span];

View File

@ -14,7 +14,9 @@ import org.hibernate.test.bytecode.enhancement.lazy.group.SimpleLazyGroupUpdateT
import org.hibernate.test.bytecode.enhancement.association.InheritedAttributeAssociationTestTask; import org.hibernate.test.bytecode.enhancement.association.InheritedAttributeAssociationTestTask;
import org.hibernate.test.bytecode.enhancement.otherentityentrycontext.OtherEntityEntryContextTestTask; import org.hibernate.test.bytecode.enhancement.otherentityentrycontext.OtherEntityEntryContextTestTask;
import org.hibernate.test.bytecode.enhancement.cascade.CascadeWithFkConstraintTestTask; import org.hibernate.test.bytecode.enhancement.cascade.CascadeWithFkConstraintTestTask;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.FailureExpected; import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.bytecode.enhancement.EnhancerTestContext; import org.hibernate.testing.bytecode.enhancement.EnhancerTestContext;
import org.hibernate.testing.bytecode.enhancement.EnhancerTestUtils; import org.hibernate.testing.bytecode.enhancement.EnhancerTestUtils;
@ -122,6 +124,7 @@ public class EnhancerTest extends BaseUnitTestCase {
@Test @Test
@TestForIssue( jiraKey = "HHH-11173" ) @TestForIssue( jiraKey = "HHH-11173" )
@RequiresDialectFeature( DialectChecks.SupportsIdentityColumns.class)
public void testLazyCache() { public void testLazyCache() {
EnhancerTestUtils.runEnhancerTestTask( LazyInCacheTestTask.class ); EnhancerTestUtils.runEnhancerTestTask( LazyInCacheTestTask.class );
} }
@ -162,6 +165,17 @@ public class EnhancerTest extends BaseUnitTestCase {
EnhancerTestUtils.runEnhancerTestTask( SimpleLazyGroupUpdateTestTask.class ); EnhancerTestUtils.runEnhancerTestTask( SimpleLazyGroupUpdateTestTask.class );
} }
@Test
@TestForIssue( jiraKey = "HHH-11506" )
public void testLazyGroupsUpdateWithoutDirtyChecking() {
EnhancerTestUtils.runEnhancerTestTask( SimpleLazyGroupUpdateTestTask.class , new EnhancerTestContext() {
@Override
public boolean doDirtyCheckingInline(CtClass classDescriptor) {
return false;
}
} );
}
@Test @Test
public void testLazyCollectionNoTransactionHandling() { public void testLazyCollectionNoTransactionHandling() {
EnhancerTestUtils.runEnhancerTestTask( LazyCollectionNoTransactionLoadingTestTask.class ); EnhancerTestUtils.runEnhancerTestTask( LazyCollectionNoTransactionLoadingTestTask.class );