When you initialize a map that is annotated with @ElementCollection and @LazyCollection(LazyCollectionOption.EXTRA) any changes to the embeddables are not written to the database.
Reproducer:
{code:java}package org.hibernate.bugs;
import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test;
/** * This template demonstrates how to develop a test case for Hibernate ORM, using the Java * Persistence API. */ public class JPAUnitTestCase {
private EntityManagerFactory entityManagerFactory;
@Before public void init() { entityManagerFactory = Persistence.createEntityManagerFactory("templatePU"); }
@After public void destroy() { entityManagerFactory.close(); }
@Test public void hhh123Test() throws Exception { // Given: EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); String primaryKey = "chewing gum"; Product product1 = new Product(primaryKey); product1.setPrice("France", 100); entityManager.persist(product1); entityManager.getTransaction().commit();
// When: entityManager.clear();
entityManager.getTransaction().begin(); Product product2 = entityManager.find(Product.class, primaryKey); product2.setPrice("France", 999); entityManager.getTransaction().commit();
// Then: entityManager.getTransaction().begin(); Product product3 = entityManager.find(Product.class, primaryKey); long actual = product3.getPrice("France"); entityManager.getTransaction().commit();
entityManager.close(); Assert.assertEquals(999L, actual); entityManager.close(); } }{code}
{noformat}package org.hibernate.bugs;
import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Optional; import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.Id; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption;
@Entity public class Product { @Id private String name;
@ElementCollection @LazyCollection(LazyCollectionOption.EXTRA) private Map<String, Price> prices = new HashMap<>();
Product() {}
public Product(String name) { this.name = name; }
public void setPrice(String country, long cents) { Price price = prices.computeIfAbsent(country, it -> new Price()); price.setCents(cents); }
public Long getPrice(String country) { return Optional.ofNullable(prices.get(country)).map(it -> it.getCents()).orElse(null); }
@Override public int hashCode() { return Objects.hash(name, prices); }
@Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Product other = (Product) obj; return Objects.equals(name, other.name) && Objects.equals(prices, other.prices); }
@Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Product [name="); builder.append(name); builder.append(", prices="); builder.append(prices); builder.append("]"); return builder.toString(); } }{noformat}
{noformat}package org.hibernate.bugs;
import java.util.Objects; import javax.persistence.Column; import javax.persistence.Embeddable;
@Embeddable public class Price { @Column private long cents;
Price() {}
public Price(long cents) { this.cents = cents; }
public long getCents() { return cents; }
public void setCents(long cents) { this.cents = cents; }
@Override public int hashCode() { return Objects.hash(cents); }
@Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Price other = (Price) obj; return cents == other.cents; }
@Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Price [cents="); builder.append(cents); builder.append("]"); return builder.toString(); } }{noformat} |
|