【发布时间】:2013-02-14 09:07:11
【问题描述】:
我有以下商业模式:
膳食 - 包含名称和价格
菜单 - 包含名称和一组膳食及其数量和替代价格(通常低于默认价格)。
过去我曾使用HashMap<Entity, Value> 解决过类似的问题。在这种情况下,我有两个值:价格和数量。由于 Java 和 JPA 不支持多映射,我决定使用两个包含相同键的 HashMap。
@Entity
public class Menu {
@Column
private String name;
@ElementCollection
@CollectionTable(name = "MENU_MEALS", joinColumns = @JoinColumn(name = "MENU_ID"))
@MapKeyJoinColumn(name = "MEAL_ID", referencedColumnName = "ID")
@Column(name="AMOUNT")
private Map<Meal, BigDecimal> amounts = new LinkedHashMap<Meal, BigDecimal>();
@ElementCollection
@CollectionTable(name = "MENU_MEALS", joinColumns = @JoinColumn(name = "MENU_ID"))
@MapKeyJoinColumn(name = "MEAL_ID", referencedColumnName = "ID")
@Column(name="PRICE")
private Map<Meal, BigDecimal> prices = new LinkedHashMap<Meal, BigDecimal>();
}
生成的表看起来不错:MENU_ID、MEAL_ID、AMOUNT、PRICE。
我像这样(在我的实体内部的一个方法中)向菜单添加新餐点,并且在它分离时执行此操作(不想立即将餐点存储到数据库 - 首先是 GUI 预览):
menu.prices.add(meal, price);
menu.amounts.add(meal, amount);
在分离的菜单中添加足够的餐食并单击“确定”按钮后,我的菜单被合并。
em.merge(menu) 操作映射为以下 SQL:
insert into MENU_MEAL (MENU_ID, MEAL_ID, PRICE) values (?, ?, ?)
insert into MENU_MEAL (MENU_ID, MEAL_ID, AMOUNT) values (?, ?, ?)
这就是问题所在。我得到一个主键约束违反异常。第二次调用应该更新 (MENU_ID, MEAL_ID) 条目,而不是尝试插入具有相同外键的新条目。
有什么建议可以强制它执行“update-if-exists-insert-otherwise”吗?
我通过将每个 HashMap 映射到不同的表来临时解决了这个问题。但我不喜欢这种解决方案。
编辑:我需要我的合并行为如下:
insert into MENU_MEAL (MENU_ID, MEAL_ID, PRICE) values(?, ?, ?) on duplicate key update PRICE=values(price)
有什么想法可以实现吗?
【问题讨论】: