为什么 hibernate 执行两个查询来急切加载 @OneToOne 双向关联?
我有一个实体 A,它有一个 B 实体,而 B 有一个带有 @OneToOne 双向关联的 A。
现在,当我找到所有A记录时,hibernate会在B上执行两个带有左外连接的查询,如下所示:
select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b;
select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b WHERE b.id=?
第一个查询加载A和B字段并且没问题,但为什么要执行第二个查询来重新加载A? 我认为这个查询加载了 B 中的 A 内容,但是这个 A 显然是包含 B 的 A...所以它已经加载了第一个查询,不是吗?
-- 编辑 --
实体 A:
@Entity
public class A implements Serializable{
// id and other ecc ecc
@OneToOne
@JoinColumn(name="id_b")
B b;
}
实体 B:
@Entity
public class B implements Serializable{
// id and other ecc ecc
@OneToOne(mappedBy="b")
A a;
}
就是这种情况,A 上的 findAll 需要两次查询...为什么?
i have entity A that has-a B entity, and B has-a A with @OneToOne bidirectional association.
Now, when i findall A records, hibernate perform two queries with a left outer join on B, something like this:
select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b;
select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b WHERE b.id=?
First query load A and B fields and it is ok, but why perform second query to reload A?
I think this query load the A content in B, but this A is obviusly the A that contains B... so its already loaded with first query, isn't true?
-- EDIT --
Entity A:
@Entity
public class A implements Serializable{
// id and other ecc ecc
@OneToOne
@JoinColumn(name="id_b")
B b;
}
Entity B:
@Entity
public class B implements Serializable{
// id and other ecc ecc
@OneToOne(mappedBy="b")
A a;
}
This is the situation, and a findAll on A need two queries... why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
打击,如果 A 和 B 共享相同的主键列,并且两个实体使用其主键连接,则您应该使用 @PrimaryKeyJoinColumn
而 B 注意您不需要mappedBy属性,因为@PrimaryKeyJoinColumn
让我们测试一下(如果你愿意,你可以测试)
注意我使用MutableInt字段(封装由Integer属性)而不是 Integer,因为 Integer 是一种不可变类型,A 和 B 共享相同的指定 id
但如果 A 和 B 使用主键以外的其他方式连接,你应该使用@JoinColumn和mappedBy(双向关系,右)如下
并且B
来测试
通过使用所有者方B,你将得到两个选择语句它发生是因为B表确实不包含任何指向表 A 的外键列但是通过使用
您将得到仅一个 select 语句,因为 A 知道如何使用其 B_ID 外键列检索其连接的 B
Blow, if A and B share The same primary key column where both entities are joined by using their primary key, you should use @PrimaryKeyJoinColumn instead
And B Notice you do not need mappedBy attribute because of @PrimaryKeyJoinColumn
Let's Test (You can Test if you want)
Notice I use a MutableInt field (encapsulated by a Integer property) instead of Integer because Integer is a immutable Type as a way Both A and B share The SAME assigned id
But if A and B are joined by using other Than their primary key, you should use @JoinColumn and mappedBy (bi-directional relationship, right) as follows
And B
To test
By using The owner side B, you will get Two select statements It occurs because B Table does not contain any foreign key column which points To Table A But by using
You will get just one select statement because A knows how To retrieve its joined B by using its B_ID foreign key column
您的映射到底是什么样子的?
您的
A
和B
类是否正确实现了hashCode()
和equals()
,以便 Hibernate 可以知道B
指向的A
实例与第一个A
实例是同一个实例吗?听起来您正在尝试对双向一对一映射进行建模 - 看看 手册中有关此内容的部分 查看实现它的推荐方法。
What does your mapping look like exactly?
Do your
A
andB
classes correctly implementhashCode()
andequals()
so that Hibernate can tell that theA
instance pointed to byB
is the same instance of the firstA
?Sounds like you are trying to model a bi-directional one-to-one mapping - take a look at the section in the manual on this to see the recommended methods for accomplishing it.