具有多个多对多关系的休眠批处理事务

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)

否则,您应该在每个 EntityAEntityB 上调用 save。

【讨论】:

EntityA 和 EntityB 之前保存...我观察到的是关系表中的更新在第三种情况下没有使用批量插入 无论如何我都尝试更改级联类型,但没有任何区别......我的问题不在于在数据库中创建 EntityA 和 EntityB。我的问题是关于 Hibernate 如何在关系表 Main_A 和 Main_B 中插入数据......在第三种情况下,不使用批量插入,并且 Hibernate 执行 300 个插入查询而不是 1。这在场景 1 和 2 中没有发生,我还没找到解释!

以上是关于具有多个多对多关系的休眠批处理事务的主要内容,如果未能解决你的问题,请参考以下文章

如何在休眠中处理多个会话事务提交和回滚?

Django ORM 处理多个多对多关系的方式

typeORM 多对多关系不同情况的处理

Django:表多对多查询聚合分组FQ查询事务

在 CloudKit 中处理多对多关系

MySQL 多表-事务