【发布时间】:2013-09-26 17:13:38
【问题描述】:
我对 Hibernate 处理插入 JoinTable 的方式有点困惑。
我需要在 JoinTable 中添加一些额外的字段,所以我选择了一种非常常见的方式,为 JoinTable 创建一个@Entity 并使用@OneToMany 和@ManyToOne。因为关系应该是唯一的,所以我在 JoinTable-Entity 中创建了一个@EmbeddedId。
让我们调用 A、B 和 AB 类:
@Entity
public class A implements Serializable {
@OneToMany(mappedBy="a", cascade=CascadeType.ALL, orphanRemoval=true)
private Set<AB> abs;
}
@Entity
public class B implements Serializable {
@OneToMany(mappedBy="b", cascade=CascadeType.ALL, orphanRemoval=true)
private Set<AB> abs;
}
@Entity
public class AB implements Serializable {
@Embeddable
public static class Id implements Serializable {
UUID aId;
UUID bId;
public Id(UUID aId, UUID bId) {
this.aId = aId;
this.bId = bId;
}
}
public AB(A a, B b) {
this.id.aId = a.getId();
this.id.bId = b.getId();
this.a = a;
this.b = b;
}
@EmbeddedId
private Id id;
@MapsId("aId")
@ManyToOne
@JoinColumn(nullable=false, updatable=false)
private A a;
@MapsId("bId")
@ManyToOne
@JoinColumn(nullable=false, updatable=false)
private B b;
}
我的常见情况是,我想在 JoinTable 中插入多个新条目。所以我有一个A_id 和多个B_ids。在纯 SQL 中,我只需执行一次查询即可完成所有操作。如果关系已经存在,数据库将抛出错误。
使用休眠我需要:
-
SELECT:给我一个A类的实例,因为 id =A_id -
SELECT:给我一个B类的实例,用于 id =B_id1或 id =B_id2或 ... - 创建类
AB的新实例并设置复合主键并保存AB
最后一步产生(对于每个AB):
- 从 AB 中选择 *,其中 a_id = ... 和 b_id = ...
- 插入 AB (aId, bId) 值 (..., ...)
这是我的代码。使用spring数据jpa(JpaRepository):
A a = aRepo.findOne(aId);
List<B> bs = bRepo.findAll(bIdList);
for(B b : bs) {
AB ab = new AB(a, b);
abRepo.save(ab);
}
groupUserRepo.flush();
如果我只是用 AB 对象创建一个新的 ArrayList,然后一次保存所有这些对象,或者像上面的代码中那样做,这并不重要。它总是对每个对象进行选择和插入。
有没有办法用更少的查询来做到这一点?
【问题讨论】:
-
stackoverflow.com/questions/5127129/… 有一些有用的信息。
-
Hibernate 必须执行的那些额外查询没有任何意义
标签: sql spring hibernate optimization query-optimization