I'm using Hibernate 3.6.10.Final and I'm on Java 1.6.
Structure:
@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;
}
SQL generated by Hibernate:
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 = ?
When I do a select on TEST
Hibernate does N queries on TEST_TEAM
and TEAM
.
How can I avoid this or how can I reduce the amount of queries? However all data is required on load time.
It's a fetch problem. Your relations have a FetchType.EAGER
so Hibernate will load all the relations with the selected model. You can switch to FetchType.LAZY
in order to avoid all the joins, but not always is a good choice.
So your relation will become:
@OneToOne
@JoinColumn(name="TEAM_ID", referencedColumnName="ID", insertable=false, updatable=false)
@OneToOne(fetch = FetchType.LAZY, targetEntity = Team.class)
private Team team;
Have a look at this question regarding the difference between EAGER and LAZY fetch and maybe look on google for some tutorials in order to achive your goal.
Solution is to ditch the join table and have a direct reference between Test <> Team.
The SQL you are seeing makes sense as Hibernate cannot know that TestTeam will be the same entity referenced by Test and 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**
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.