I have couple of entities and DAO for work with database, all working fine without second level cache. But when enabling cache - obj in cache not updating with CacheConcurrencyStrategy.READ_WRITE or CacheConcurrencyStrategy.TRANSACTIONAL. Only with CacheConcurrencyStrategy.NONE all working fine. Any ideas how to fix it?
Last assert return 42, but in DB already 140
Entity
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import java.util.Objects;
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
@Table(name = "purchased_products", schema = "purchase", catalog = "onlineshop_purchase")
public class PurchasedProducts {
@Setter(AccessLevel.NONE)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id", nullable = false)
private Long id;
/**
* Couple of "PurchasedProducts" relating to 1 "Purchase"
*/
@ManyToOne
@JoinColumn(name = "purchase_id", referencedColumnName = "id")
private Purchase purchase;
/**
* Couple of "PurchasedProducts" relating to 1 "Product"
*/
@ManyToOne
@JoinColumn(name = "product_id", referencedColumnName = "id")
private Product product;
/**
* Actual price taking from "Product" during creation "PurchasedProducts"
*/
@Basic
@Column(name = "product_price", nullable = false, precision = 0)
private Double productPrice;
@Basic
@Column(name = "product_qty", nullable = false, precision = 0)
private Double productQty;
/**
* Counting by trigger in DB
*/
@Setter(AccessLevel.NONE)
@Basic
@Column(name = "total_amount", nullable = true, precision = 0)
private Double totalAmount;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PurchasedProducts that = (PurchasedProducts) o;
return id.equals(that.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
Here is problematic test:
/**
* Setup data for main tests
*/
// 1. Creating new Customer
static CustomerDAOImpl customerDAO = new CustomerDAOImpl();
static Customer customer = new Customer();
static Long customerId;
static CustomerRoleDAOImpl customerRoleDAO = new CustomerRoleDAOImpl();
// 2. Creating new Products
static ProductDAOImpl productDAO = new ProductDAOImpl();
static Product product1 = new Product();
static Product product2 = new Product();
static Double product1Qty = 3D;
static Double product2Qty = 2D;
static Long product1Id;
static Long product2Id;
// 3. Creating new Purchase
static PurchaseDAOImpl purchaseDAO = new PurchaseDAOImpl();
static Purchase purchase = new Purchase();
static Long purchaseId;
// 4. Creating list with purchased products
static PurchasedProductsDAOImpl purchasedProductsDAO = new PurchasedProductsDAOImpl();
static PurchasedProducts purchasedProduct1 = new PurchasedProducts();
static Long purchasedProduct1Id;
static PurchasedProducts purchasedProduct2 = new PurchasedProducts();
static Long purchasedProduct2Id;
static List<PurchasedProducts> purchasedProducts;
@BeforeAll
static void setupAndCheckTestData() {
// Creating Customer
customer.setCustomerName("customerNameTest");
customer.setCustomerSurname("customerSurnameTest");
customer.setCustomerEmail("customerEmailTest");
customer.setCustomerPassword("customerPasswordTest");
customerDAO.add(customer);
customerId = customer.getId();
assertTrue(customerDAO.get(customerId).equals(customer));
// Creating 2 products
product1.setItem("TestProduct1");
product1.setPrice(14D);
product2.setItem("TestProduct2");
product2.setPrice(19D);
productDAO.add(product1);
productDAO.add(product2);
product1Id = product1.getId();
product2Id = product2.getId();
assertEquals(productDAO.get(product1Id), product1);
assertEquals(productDAO.get(product2Id), product2);
// Creating new purchase ang getting purchase ID for assigning purchased products
purchase.setCustomerId(customerId);
purchaseDAO.add(purchase);
purchaseId = purchase.getId();
// Creating 2 purchased products from products
purchasedProduct1.setPurchase(purchase);
purchasedProduct1.setProduct(product1);
purchasedProduct1.setProductQty(product1Qty);
purchasedProduct1.setProductPrice(product1.getPrice());
purchasedProductsDAO.add(purchasedProduct1);
purchasedProduct1Id = purchasedProduct1.getId();
purchasedProduct2.setPurchase(purchase);
purchasedProduct2.setProduct(product2);
purchasedProduct2.setProductQty(product2Qty);
purchasedProduct2.setProductPrice(product2.getPrice());
purchasedProductsDAO.add(purchasedProduct2);
purchasedProduct2Id = purchasedProduct2.getId();
}
/**
* Main functionality tests for PurchasedProducts
*/
@Test
void purchasedProducts_Update(){
// Expected 42 because Product1 price = 14 * product1Qty = 3
assertEquals(42D, purchasedProductsDAO.get(purchasedProduct1Id).getTotalAmount());
purchasedProduct1 = purchasedProductsDAO.get(purchasedProduct1Id);
purchasedProduct1.setProductQty(10D);
purchasedProductsDAO.update(purchasedProduct1);
// Expected 140 because Product1 price = 14 * product1Qty = 10
assertEquals(140D, purchasedProductsDAO.get(purchasedProduct1Id).getTotalAmount().doubleValue());
}
Trigger in PostgreSQL which updating purchase_price
DECLARE
purchaseId INTEGER = new.purchase_id;
BEGIN
UPDATE purchase.purchase_data SET purchase_price = (SELECT SUM(total_amount) FROM purchase.purchased_products WHERE purchase_id = purchaseId) WHERE id = purchaseId;
RETURN NEW;
END