我正在使用Hibernate 3.6.10.Final和我在Java 1.6上。
结构:
@Entity
class Test
{
@Id
private String id;
@OneToOne(mappedBy = "test")
private Test_Team test_team;
}
@Entity
class Test_Team
{
@Id
private long id;
@OneToOne
@JoinColumn(name = "TEST_ID", referencedColumnName = "ID", insertable = false, updatable = false)
private Test test;
@OneToOne
@JoinColumn(name="TEAM_ID", referencedColumnName="ID", insertable=false, updatable=false)
private Team team;
}
class Team
{
@Id
private long id;
@OneToOne(mappedBy="team")
private Test_Team test_team;
}
Hibernate生成的SQL:
SELECT *
FROM (SELECT test0_.id
FROM test test0_ )
WHERE rownum <= 1 // LIMIT 1
SELECT test_team0_.id,
test_team0_.team_id,
test_team0_.test_id,
team1_.id,
test2_.id,
FROM test_team test_team0_
LEFT OUTER JOIN team team1_
ON test_team0.team_id = team1_.id
LEFT OUTER JOIN test test2_
ON test_team0_.test_id = test2_.id
WHERE test_team_.test_id = ?
SELECT test_team0_.id,
test_team0.team_id,
test_team0.test_id,
team1_.id,
test2_.id,
FROM test_team test_team0_
LEFT OUTER JOIN team team1_
ON test_team0_.team_id = team1_.id
LEFT OUTER JOIN test test2_
ON test_team0_.test_id = test2_.id
WHERE test_team0_.team_id = ?
当我对TEST
进行选择时,Hibernate会在TEST_TEAM
和TEAM
上进行N次查询。
如何避免这种情况或如何减少查询量?但是,加载时需要所有数据。
答案 0 :(得分:0)
这是一个获取问题。你的关系有一个FetchType.EAGER
所以Hibernate会加载所选模型的所有关系。您可以切换到FetchType.LAZY
以避免所有连接,但并不总是一个不错的选择。
所以你的关系将成为:
@OneToOne
@JoinColumn(name="TEAM_ID", referencedColumnName="ID", insertable=false, updatable=false)
@OneToOne(fetch = FetchType.LAZY, targetEntity = Team.class)
private Team team;
关于 EAGER 和 LAZY fetch之间的区别,请查看this question,并在google上查看一些教程,以实现目标。< / p>
答案 1 :(得分:0)
解决方案是抛弃连接表并在Test&lt;&gt;之间进行直接引用。球队。
您看到的SQL很有意义,因为Hibernate无法知道TestTeam将与Test和Team引用的实体相同。
Test test = .../
test.getTestTeam();//triggers load **where test_id = test.id**
Team team = test.getTestTeam().getTeam();
team.getTestTeam();// triggers load **where team_id = team.id**