还有另一个多对多的Hibernate问题。我有最简单的多对多映射,如下所示:
@Entity
public class Strategy implements Serializable {
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "STRATEGY_TO_GROUP", joinColumns = {@JoinColumn(name="STRATEGY_ID")}, inverseJoinColumns = {@JoinColumn(name = "STRATEGY_GROUP_ID")})
private Set<StrategyGroup> groups;
...
}
关系的另一面如下:
@Entity
public class StrategyGroup implements Serializable {
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "STRATEGY_TO_GROUP", joinColumns = {@JoinColumn(name="STRATEGY_GROUP_ID")}, inverseJoinColumns = {@JoinColumn(name = "STRATEGY_ID")})
private Set<Strategy> strategies = new HashSet<Strategy>();
我现在要做的是以最简单的方式清空两个表。我正在尝试跟随(em是我的entityManager)。
em.createQuery("delete from StrategyGroup sg").executeUpdate();
em.createQuery("delete from Strategy s").executeUpdate();
这使我在@joinTable上违反约束。另一方面,如果我按em.remove(strategyGroup);
删除,则工作正常 - 策略组将被删除,并且@joinTable会正确更新。
那么如何清空桌子呢?我是否需要加载对象并逐个删除它们?
感谢您的帮助。
答案 0 :(得分:3)
首先,您的映射是错误的。关联的一方必须是所有者方,并定义关联的映射。另一个必须是inserse一侧,只需使用mappedBy属性:
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "groups")
private Set<Strategy> strategies = new HashSet<Strategy>();
其次,你应该真的避免在toMany关联上获取EAGER,特别是在双方:这会强制Hibernate以递归方式加载所有相关实体,并且很有可能在内存中加载两个表的所有行你加载一行的时间。
现在回答你的问题:
如果要从两个表中删除所有内容,首先需要确保连接表为空,否则其中一个表中的某些行仍然会被连接表的一行引用,并且它会显而易见失败。为此,您的最佳选择是在执行已有的两个HQL查询之前使用SQL查询从连接表中删除所有内容。