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 7af7ec63ac..98c08e670f 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 @@ -779,8 +779,8 @@ private String generateUnexpectedSessionStateMessage(SharedSessionContractImplem @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 @@ -790,7 +790,7 @@ public boolean needsRecreate(CollectionPersister persister) { // 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(); } @@ -798,8 +798,8 @@ public boolean needsRecreate(CollectionPersister persister) { 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 fcfdc01847..37441ba928 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/AnyType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/AnyType.java @@ -394,6 +394,11 @@ public boolean hasNotNullProperty() { 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 1cda811876..90168313e7 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java @@ -66,6 +66,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen private final boolean isKey; private boolean hasNotNullProperty; private final CompositeUserType compositeUserType; + private boolean hasNullProperty; private EmbeddableValuedModelPart mappingModelPart; @@ -91,9 +92,12 @@ public ComponentType(Component component, int[] originalPropertyOrder, MetadataB 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++; } @@ -814,6 +818,11 @@ public boolean hasNotNullProperty() { 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 fffc7afb05..57b3c56326 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CompositeType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CompositeType.java @@ -138,6 +138,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. *