1

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.

martinyyyy
  • 1,652
  • 3
  • 21
  • 44

2 Answers2

0

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.

Community
  • 1
  • 1
IlGala
  • 3,331
  • 4
  • 35
  • 49
  • I already thought about this but I need everything on load time. So using LAZY fetch wouldn't make any difference, I extended my question and added this information – martinyyyy Nov 17 '15 at 12:11
0

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**
Alan Hay
  • 22,665
  • 4
  • 56
  • 110