h5. Description
I'm migrating from hibernate 5.6.15 to hibernate 6.2.5 and I have noticed some issues when I try to delete an entity that contains an embedded which contain itself have a compositeId with one of its id field describing part of a many to many @ManyToOne association. h3. Entities
{ code:java noformat }@Getter @ Entity IdClass(ProductPK.class) @ ToString EqualsAndHashCode (onlyExplicitlyIncluded = true) @ EqualsAndHashCode ToString (onlyExplicitlyIncluded = true) @NoArgsConstructor(access = PROTECTED) @ Table(name = "TAG_OPERATORS") Entity @OptimisticLocking(type = OptimisticLockType.DIRTY) @DynamicUpdate @Cacheable @ org.hibernate.annotations. Cache(usage = READ_WRITE) @Table(name = "PRODUCTS") public class TagOperator Product { public TagOperator Product (String operatorId productId, Operator operator ) { this. operatorId productId = operatorId productId ; this. tagPolicy operator = new OperatorTagPolicy(Set.of(), ALL) operator ; }
@EqualsAndHashCode.Include @ToString.Include @Id @Column(name = " OPERATOR_ID PRODUCT_ID ", nullable = false) private String operatorId productId ; @ Embedded Id private OperatorTagPolicy tagPolicy;
@ Value EqualsAndHashCode.Include @ AllArgsConstructor ToString.Include @ NoArgsConstructor(access = PROTECTED) Getter @ Embeddable Setter public static class OperatorTagPolicy { @ NonFinal @ManyToMany Cache ( fetch usage = LAZY READ_WRITE ) @ JoinTable ManyToOne ( name fetch = "OPERATOR_TO_TAG" LAZY , joinColumns optional = { false) @JoinColumn( name nullable = "OPERATOR_ID", referencedColumnName = "OPERATOR_ID" false ) }, private Operator operator; inverseJoinColumns = @ JoinColumn Column (name = " TAG_NAME DESCRIPTION ") ) @ org.hibernate.annotations.Cache(usage = READ_WRITE) Setter Set<Tag> exceptions private String description ;
@ NonFinal AllArgsConstructor @ Column(name = "TAG_POLICY_TYPE", nullable = false) EqualsAndHashCode @ Enumerated ToString @NoArgsConstructor ( EnumType.STRING access = PUBLIC ) PolicyType type public static class ProductPK implements Serializable { private String productId ; private String operator; } } { code noformat }
{ code:java noformat }@ Getter @ Entity @ Table ToString ( name onlyExplicitlyIncluded = "TAGS" true ) @EqualsAndHashCode (onlyExplicitlyIncluded = true) @NoArgsConstructor(access = PROTECTED) @ AllArgsConstructor Table(name = "OPERATORS") @ Getter OptimisticLocking(type = OptimisticLockType.DIRTY) @DynamicUpdate @Cacheable @Cache(usage = READ_WRITE) public class Tag Operator { public Operator(String operatorId) { this.operatorId = operatorId; }
@ EqualsAndHashCode.Include @ToString.Include @ Id @Column(name = " TAG_NAME OPERATOR_ID ", nullable = false) private String name operatorId ; }{code}
@OneToMany(mappedBy = "operator", cascade = { code:java CascadeType.ALL } , orphanRemoval = true, fetch = FetchType.LAZY) private List<Product> products = new ArrayList<>();
public enum PolicyType void setProducts(List<Product> products) { ALL, this.products = products; NONE } }{ code noformat }
h3. Test
{ code:java noformat } @Test void shouldDeleteTagOperator shouldDeleteProduct () { // Given String string = "ID2"; String operatorID = " tagOperatorID operatorID2 "; TagOperator String test = "test"; Operator operator = new TagOperator Operator (operatorID); tagOperatorService operatorService . addTagOperator addOperator (operator); Product product = new Product(string, operator); tagOperatorService product . deleteTagOperator setDescription ( test); productService.addProduct(product);
// When ProductPK productPK = new ProductPK(string, operatorID); productService.deleteProduct(productPK); // Then Optional< TagOperator Product > byId2 = tagOperatorService productService . getTagOperator getProduct ( operatorID productPK ); assertThat(byId2).isEmpty(); }{ code noformat }
These tests raise an exception when I get the delete (or deleteAll) is committed.
{noformat}org.springframework.transaction.TransactionSystemException following exception : Could not commit JPA transaction at org.springframework.orm. jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java ObjectOptimisticLockingFailureException : 570) ... Caused by Batch update returned unexpected row count from update [0]; actual row count : jakarta.persistence.RollbackException 0; expected : Error while committing the transaction ... Caused by 1; statement executed : java.lang.UnsupportedOperationException delete from products where operator_operator_id=? and product_id=? and operator_operator_id is null and product_id is null and description=? {noformat} at org. hibernate springframework . metamodel orm . mapping jpa . internal vendor . PluralAttributeMappingImpl HibernateJpaDialect . breakDownJdbcValues convertHibernateAccessException ( PluralAttributeMappingImpl HibernateJpaDialect .java: 975 307 ) at org. hibernate springframework . metamodel orm . mapping jpa . internal vendor . EmbeddableMappingTypeImpl HibernateJpaDialect . breakDownJdbcValues translateExceptionIfPossible ( EmbeddableMappingTypeImpl HibernateJpaDialect .java: 655 232 ) ... {noformat}
h3. Be aware that the right attachment archive is the latest uploaded (I cannot delete attachment that were already uploaded).
GitHub repository with sources : [https://github.com/emouty/hibernate-issues|https://github.com/emouty/hibernate-issues|smart-link] |
|