HHH-17334 Simplify indexed element collection update and assert element column mutability

This commit is contained in:
Marco Belladelli 2023-11-23 21:40:47 +01:00 committed by Christian Beikov
parent f55e2334a4
commit defdfc54f4
4 changed files with 44 additions and 47 deletions

View File

@ -2179,6 +2179,7 @@ else if ( isManyToAny ) {
} }
checkFilterConditions( collection ); checkFilterConditions( collection );
checkConsistentColumnMutability( collection );
} }
private void handleElementCollection(XClass elementType, String hqlOrderBy) { private void handleElementCollection(XClass elementType, String hqlOrderBy) {
@ -2666,6 +2667,34 @@ private static void checkFilterConditions(Collection collection) {
} }
} }
private static void checkConsistentColumnMutability(Collection collection) {
checkConsistentColumnMutability( collection.getRole(), collection.getKey() );
checkConsistentColumnMutability( collection.getRole(), collection.getElement() );
}
private static void checkConsistentColumnMutability(String collectionRole, Value value) {
Boolean readOnly = null;
for ( int i = 0; i < value.getColumnSpan(); i++ ) {
final boolean insertable = value.isColumnInsertable( i );
if ( insertable != value.isColumnUpdateable( i ) ) {
throw new AnnotationException(
"Join column '" + value.getColumns().get( i ).getName() + "' on collection property '"
+ collectionRole + "' must be defined with the same insertable and updatable attributes"
);
}
if ( readOnly == null ) {
readOnly = insertable;
}
else if ( readOnly != insertable && !value.getColumns().get( i ).isFormula() ) {
// We also assert that all join columns have the same mutability (except formulas)
throw new AnnotationException(
"All join columns on collection '" + collectionRole + "' should have" +
" the same insertable and updatable setting"
);
}
}
}
private void bindCollectionSecondPass(PersistentClass targetEntity, AnnotatedJoinColumns joinColumns) { private void bindCollectionSecondPass(PersistentClass targetEntity, AnnotatedJoinColumns joinColumns) {
if ( !isUnownedCollection() ) { if ( !isUnownedCollection() ) {

View File

@ -491,32 +491,8 @@ private RestrictedTableMutation<JdbcMutationOperation> generateUpdateRowAst(Muta
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// SET // SET
if ( hasIndex() ) { attribute.getElementDescriptor().forEachUpdatable( updateBuilder );
/*
Given :
class MyEntity {
@ElementCollection(fetch = FetchType.LAZY)
@OrderColumn
private List<MyEmbeddable> myEmbeddables;
}
@Embeddable
public static class MyEmbeddable {
@Column(updatable = false)
private String embeddedProperty;
}
we cannot understand if the update is due to a change in the value embeddedProperty or because a
new element has been added to the list in an existing position (update) shifting the old value (insert).
For this reason we cannot take into consideration the `@Column(updatable = false)`
*/
attribute.getElementDescriptor().forEachNonFormula( updateBuilder );
}
else {
attribute.getElementDescriptor().forEachUpdatable( updateBuilder );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// WHERE // WHERE
@ -552,28 +528,16 @@ private void applyUpdateRowValues(
0, 0,
jdbcValueBindings, jdbcValueBindings,
null, null,
hasIndex() ? (valueIndex, bindings, y, jdbcValue, jdbcValueMapping) -> {
(valueIndex, bindings, y, jdbcValue, jdbcValueMapping) -> { if ( !jdbcValueMapping.isUpdateable() || jdbcValueMapping.isFormula() ) {
if ( jdbcValueMapping.isFormula() ) { return;
return; }
} bindings.bindValue(
bindings.bindValue( jdbcValue,
jdbcValue, jdbcValueMapping,
jdbcValueMapping, ParameterUsage.SET
ParameterUsage.SET );
); },
}
:
(valueIndex, bindings, y, jdbcValue, jdbcValueMapping) -> {
if ( !jdbcValueMapping.isUpdateable() || jdbcValueMapping.isFormula() ) {
return;
}
bindings.bindValue(
jdbcValue,
jdbcValueMapping,
ParameterUsage.SET
);
},
session session
); );
} }

View File

@ -8,6 +8,7 @@
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.Column; import jakarta.persistence.Column;
@ -26,6 +27,7 @@
}) })
@SessionFactory @SessionFactory
@JiraKey("HHH-16573") @JiraKey("HHH-16573")
@Disabled("We now assert that collection columns have the same insertable / updatable attributes, see HHH-17334")
public class EmbeddableAsElementCollectionWithUpdatableFalseTest { public class EmbeddableAsElementCollectionWithUpdatableFalseTest {
@AfterEach @AfterEach

View File

@ -8,6 +8,7 @@
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.Column; import jakarta.persistence.Column;
@ -27,6 +28,7 @@
}) })
@SessionFactory @SessionFactory
@JiraKey("HHH-16573") @JiraKey("HHH-16573")
@Disabled("We now assert that collection columns have the same insertable / updatable attributes, see HHH-17334")
public class EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest { public class EmbeddableAsOrderedElementCollectionWithUpdatableFalseTest {
@AfterEach @AfterEach