简体   繁体   中英

Hibernate does multiple queries on @OneToOne join

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM