h3. 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 have a compositeId with one of its id field part of a @ManyToOne association.
h3. Entities
{code:java}@Getter @IdClass(ProductPK.class) @EqualsAndHashCode(onlyExplicitlyIncluded = true) @ToString(onlyExplicitlyIncluded = true) @NoArgsConstructor(access = PROTECTED) @Entity @OptimisticLocking(type = OptimisticLockType.DIRTY) @DynamicUpdate @Cacheable @Cache(usage = READ_WRITE) @Table(name = "PRODUCTS") public class Product { public Product(String productId, Operator operator) { this.productId = productId; this.operator = operator; }
@EqualsAndHashCode.Include @ToString.Include @Id @Column(name = "PRODUCT_ID", nullable = false) private String productId; @Id @EqualsAndHashCode.Include @ToString.Include @Getter @Setter @Cache(usage = READ_WRITE) @ManyToOne(fetch = LAZY, optional = false) @JoinColumn(nullable = false) private Operator operator;
@Column(name = "DESCRIPTION") @Setter private String description;
@AllArgsConstructor @EqualsAndHashCode @ToString @NoArgsConstructor(access = PUBLIC) public static class ProductPK implements Serializable { private String productId; private String operator; } } {code}
{code:java} @Getter @Entity @ToString(onlyExplicitlyIncluded = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true) @NoArgsConstructor(access = PROTECTED) @Table(name = "OPERATORS") @OptimisticLocking(type = OptimisticLockType.DIRTY) @DynamicUpdate @Cacheable @Cache(usage = READ_WRITE) public class Operator {
public Operator(String operatorId) { this.operatorId = operatorId; }
@EqualsAndHashCode.Include @ToString.Include @Id @Column(name = "OPERATOR_ID", nullable = false) private String operatorId;
@OneToMany(mappedBy = "operator", cascade = {CascadeType.ALL}, orphanRemoval = true, fetch = FetchType.LAZY) private List<Product> products = new ArrayList<>();
public void setProducts(List<Product> products) { this.products = products; }
}{code}
h3. Test
{code:java} @Test void shouldDeleteProduct() { // Given String string = "ID2"; String operatorID = "operatorID2"; String test = "test"; Operator operator = new Operator(operatorID); operatorService.addOperator(operator); Product product = new Product(string, operator); product.setDescription(test); productService.addProduct(product);
// When ProductPK productPK = new ProductPK(string, operatorID); productService.deleteProduct(productPK);
// Then Optional<Product> byId2 = productService.getProduct(productPK); assertThat(byId2).isEmpty(); }{code}
I get the following exception :
{noformat}org.springframework.orm.ObjectOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; statement executed: delete from products where operator_operator_id=? and product_id=? and operator_operator_id is null and product_id is null and description=?
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:307) at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:232){noformat}
GitHub repository with sources : [https://github.com/emouty/hibernate-L2-cache-issue|https://github.com/emouty/hibernate-L2-cache-issue|smart-link] |
|