I have an error during an update transaction on my database using JpaRepository. I saw that there are many questions about this same error here but none of the solutions mentioned seem to solve my case. This is my main method:
public View update(Long productCode, Long customerCode, UpdateForm form) {
var entityToUpdate = repository.findByProductCodeAndCustomerCode(productCode, customerCode);
var updatedObject = new Builder(entityToUpdate).build(form);
var savedObject = repository.save(updatedObject); //error thrown here
return converter.convertToView(savedObject);
}
This is the Builder class implementation that appears above:
public class Builder {
private final Purchase entityToUpdate;
public Builder(Optional<Purchase> entityToUpdate) {
this.entityToUpdate = entityToUpdate.isPresent() ? entityToUpdate.get() : null;
}
public Purchase build(PurchaseUpdateForm form) {
this.entityToUpdate.setDiscount(form.getDiscount());
this.entityToUpdate.getId().setPurchaseBoxQuantity(form.getPurchaseBoxQuantity());
return entityToUpdate;
}
}
I tried to put an @Transactional
in the update()
and build()
methods but the error persists. I also tried using saveAndFlush
but nothing changed. Full log message:
Optimistic locking failed; nested exception is caused by: org.hibernate.StaleObjectStateException:
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):
[PurchasePK@bb7039e8]
# Additional Information - Domain
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "TB_PURCHASE")
public class Purchase {
@EmbeddedId
private PurchasePK id;
@NotNull
@Column(name = "DISCOUNT")
private BigDecimal discount;
}
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = { "product", "purchaseBoxQuantity" })
@Embeddable
public class PurchasePK {
@NotNull
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "CD_PRODUCT")
@JoinColumn(name = "CD_CUSTOMER")
private Product product;
@NotNull
@Column(name = "QT_BOXES")
private Long purchaseBoxQuantity;
}