具有多个多对多关系的休眠批处理事务
Posted
技术标签:
【中文标题】具有多个多对多关系的休眠批处理事务【英文标题】:Hibernate batch transaction with multiple ManyToMany Relations 【发布时间】:2017-06-15 15:44:15 【问题描述】:我已成功配置 Hibernate 以使用批处理查询来创建/更新对象,但有一个场景还不能正常工作。
我有 3 个实体: - 主要实体 - 实体 A - 实体 B
主实体与实体 A 和实体 B 都具有多对多关系。主实体是关系的所有者:
@ManyToMany
@JoinTable(name = "MAIN_A", joinColumns =
@JoinColumn(name = "MAIN_UID", nullable = false, updatable = false) , inverseJoinColumns =
@JoinColumn(name = "A_UID", nullable = false, updatable = false) )
private Set<EntityA> entitiesA = new HashSet<>(0);
@ManyToMany
@JoinTable(name = "MAIN_B", joinColumns =
@JoinColumn(name = "MAIN_UID", nullable = false, updatable = false) , inverseJoinColumns =
@JoinColumn(name = "B_UID", nullable = false, updatable = false) )
private Set<EntityB> entitiesB = new HashSet<>(0);
我写了一个3个简单的测试。 首先,我在数据库中创建了一些实体 A 和实体 B 行(这与所有 2 个测试用例相同)。
第一种情况: 创建 n 个主要实体,并为每个集合仅创建实体 A
结果:所有 Main Entity 和 MAIN_A 表条目只插入一个。所以在这种情况下,浴缸插入按预期工作。
第二种情况: 创建 n 个主要实体,并为每个集合仅创建实体 B
结果:所有 Main Entity 和 MAIN_B 表条目只插入一个。所以在这种情况下,浴缸插入按预期工作。
第三种情况: 创建 n 个主实体,并为每个集合创建实体 A 和实体 B
结果:所有主实体只插入一次,n 插入 MAIN A 和 MAIN_B 表条目。在这种情况下,批量插入不起作用。我用谷歌搜索并搜索,但找不到答案。
有谁知道为什么它在第三种情况下没有按预期工作?我做错什么了吗?配置中有什么可以满足我的要求吗?
3 个场景的代码非常简单:
Set<EntityA> setA;
Set<EntityB> setB;
for (long i = 1; i < n; i++)
MainEntity e = new MainEntity();
ac.setEntitiesA(setA); //this is commented in the second scenario
ac.setEntitiesB(setB); // this is commented in the first scenario
session.save(e);
我在hibernate论坛发了同样的问题:Hibernate Forum post
【问题讨论】:
你能添加用于执行第 3 个场景的代码吗? @MaciejKowalski 我刚刚用代码更新了问题 【参考方案1】:您似乎只保存了MainEntity
(我假设添加到集合中的 EntityA、B 是新实体)。
在我看来,您应该至少为每个单向关系添加这个级联选项:
@ManyToMany(cascade = CascadeType.PERSIST, CascadeType.MERGE)
否则,您应该在每个 EntityA
、EntityB
上调用 save。
【讨论】:
EntityA 和 EntityB 之前保存...我观察到的是关系表中的更新在第三种情况下没有使用批量插入 无论如何我都尝试更改级联类型,但没有任何区别......我的问题不在于在数据库中创建 EntityA 和 EntityB。我的问题是关于 Hibernate 如何在关系表 Main_A 和 Main_B 中插入数据......在第三种情况下,不使用批量插入,并且 Hibernate 执行 300 个插入查询而不是 1。这在场景 1 和 2 中没有发生,我还没找到解释!以上是关于具有多个多对多关系的休眠批处理事务的主要内容,如果未能解决你的问题,请参考以下文章