diff --git a/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java b/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java index 534cc5b222..75d9a7b2fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java +++ b/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java @@ -782,8 +782,8 @@ public abstract class AbstractPersistentCollection implements Serializable, P @Override public boolean needsRecreate(CollectionPersister persister) { - // Workaround for situations like HHH-7072. If the collection element is a component that consists entirely - // of nullable properties, we currently have to forcefully recreate the entire collection. See the use + // Workaround for situations like HHH-7072. If the collection element is a component that consists + // nullable properties, we currently have to forcefully recreate the entire collection. See the use // of hasNotNullableColumns in the AbstractCollectionPersister constructor for more info. In order to delete // row-by-row, that would require SQL like "WHERE ( COL = ? OR ( COL is null AND ? is null ) )", rather than // the current "WHERE COL = ?" (fails for null for most DBs). Note that @@ -793,7 +793,7 @@ public abstract class AbstractPersistentCollection implements Serializable, P // Selecting a type used in where part of update statement // (must match condition in org.hibernate.persister.collection.BasicCollectionPersister#doUpdateRows). // See HHH-9474 - Type whereType; + final Type whereType; if ( persister.hasIndex() ) { whereType = persister.getIndexType(); } @@ -801,8 +801,8 @@ public abstract class AbstractPersistentCollection implements Serializable, P whereType = persister.getElementType(); } if ( whereType instanceof CompositeType ) { - CompositeType componentIndexType = (CompositeType) whereType; - return !componentIndexType.hasNotNullProperty(); + final CompositeType componentIndexType = (CompositeType) whereType; + return componentIndexType.hasNullProperty(); } return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/type/AnyType.java b/hibernate-core/src/main/java/org/hibernate/type/AnyType.java index 18a66afb1d..67fc1cb09c 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/AnyType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/AnyType.java @@ -395,6 +395,11 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT return true; } + @Override + public boolean hasNullProperty() { + return false; + } + @Override public Type[] getSubtypes() { return new Type[] {discriminatorType, identifierType }; diff --git a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java index 300e8c3f51..3fe5e40007 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java @@ -63,6 +63,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen private final boolean isAggregate; private final boolean isKey; private boolean hasNotNullProperty; + private boolean hasNullProperty; private EmbeddableValuedModelPart mappingModelPart; @@ -97,9 +98,12 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen this.propertyNullability[i] = property.isOptional(); this.cascade[i] = property.getCascadeStyle(); this.joinedFetch[i] = property.getValue().getFetchMode(); - if ( !propertyNullability[i] ) { + if ( !property.isOptional() ) { hasNotNullProperty = true; } + else { + hasNullProperty = true; + } i++; } } @@ -762,6 +766,11 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen return hasNotNullProperty; } + @Override + public boolean hasNullProperty() { + return hasNullProperty; + } + @Override public Class getBindableJavaType() { return getReturnedClass(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/CompositeType.java b/hibernate-core/src/main/java/org/hibernate/type/CompositeType.java index f3aa9893e3..344bad6f42 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CompositeType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CompositeType.java @@ -158,6 +158,22 @@ public interface CompositeType extends Type { */ boolean hasNotNullProperty(); + /** + * Convenience method to quickly check if {@link #getPropertyNullability} contains a nullable sub-properties. + * + * @return {@code true} if any of the properties are nullable as indicated by {@link #getPropertyNullability}, + * {@code false} otherwise. + */ + default boolean hasNullProperty() { + final boolean[] propertyNullability = getPropertyNullability(); + for ( int i = 0; i < propertyNullability.length; i++ ) { + if ( propertyNullability[i] ) { + return true; + } + } + return false; + } + /** * Convenience method for locating the property index for a given property name. *