Well, that's a strange case that you got there and I created a test just out of curiosity. This case works as you maybe want, but not if you cascade all operations (maybe its a bug, what do the others say?)
Code:
@Entity
public class Customer {
private long id;
private Map<String, MapToMany> toManyMap;
@Id
@GeneratedValue
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@OneToMany(mappedBy="id.customer")
@MapKey(columns=@Column(name="mapKey"))
//Does not work on merge
// @Cascade({CascadeType.ALL})
//works
@Cascade({CascadeType.DELETE, CascadeType.PERSIST})
public Map<String, MapToMany> getToManyMap() {
return toManyMap;
}
public void setToManyMap(Map<String, MapToMany> toManyMap) {
this.toManyMap= toManyMap;
}
}
Code:
@Entity
public class MapToMany {
private MapToManyId id;
private BigDecimal impPart;
@EmbeddedId
public MapToManyId getId() {
return id;
}
public void setId(MapToManyId id) {
this.id = id;
}
@Column(name = "IMP_PART")
public BigDecimal getImpPart() {
return impPart;
}
public void setImpPart(BigDecimal impPart) {
this.impPart = impPart;
}
}
Code:
@Embeddable
public class MapToManyId implements Serializable
{
private Customer customer;
private String mapKey;
@ManyToOne
// @Column(name="customer_id")
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public String getMapKey() {
return mapKey;
}
public void setMapKey(String mapKey) {
this.mapKey = mapKey;
}
}
Testclass:
Code:
public class TestMap {
public static void main(String[] args) throws Exception {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("TestUnit",
Collections.EMPTY_MAP);
EntityManager em = factory.createEntityManager();
Session s = (Session) em.getDelegate();
em.getTransaction().begin();
Customer customer = em.find(Customer.class, 1L);
if(customer == null)
{
fillTables(em);
em.clear();
customer = em.find(Customer.class, 1L);
}
System.out.println(customer.getToManyMap().size());
em.clear();
System.out.println("----Cleared-----");
//causes exception, if cascaded
em.merge(customer);
em.flush();
em.getTransaction().commit();
}
private static void fillTables(EntityManager em)
{
Customer customer = new Customer();
customer.setToManyMap(new HashMap<String, MapToMany>());
MapToMany mk = new MapToMany();
MapToManyId id = new MapToManyId();
id.setCustomer(customer);
id.setMapKey("key");
mk.setId(id);
mk.setImpPart(new BigDecimal(12));
customer.getToManyMap().put(id.getMapKey(), mk);
em.persist(customer);
em.flush();
System.out.println("-----------Finished Inserting---------");
}
}
So, if you map it like this, you maybe get it working (rating is welcome, then ;-)).
But I am interested in what the others say. Is it a bug, that it does not work (infinite recursion) when merge is cascaded?