Why does Hibernate execute multiple SELECT queries instead of one when using @Fetch(FetchMode.JOIN)

后端 未结 2 1947
我寻月下人不归
我寻月下人不归 2021-01-31 04:41

I\'ve got the following query which I expect to run in a single select request:

@NamedQuery(name=Game.GET_GAME_BY_ID1,
                query = \"SELECT g FROM Ga         


        
相关标签:
2条回答
  • 2021-01-31 05:37

    The secondary queries come from:

    @ManyToOne(fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JoinColumn(name="team_id2")
    public Team getTeam2() {
        return team2;
    }
    

    So, you need to:

    1. Make all associations LAZY. By default, all @ManyToOne and @OneToOne associations are EAGER, so it's better to have them LAZY and only override the fetch plan on a query basis.

    2. Remove the @Fetch(FetchMode.JOIN), which is essentially an EAGER fetch directive. In your case, not just the team2 property is fetched, but its players and skills as well.

    0 讨论(0)
  • 2021-01-31 05:38

    You are experiencing a well known problem, a.k.a. the "N+1 selects". In short, the "N+1 selects" problem occurs when you select a parent entity and hibernate will make additional select for a child related to the parent with OneToOne. So if you have "N" parent-child records in the database, hibernate will get all parents with one select and then get each child in separated select, making total N+1 selects.
    There are two approaches for "N+1" problem in hibernate:
    1. "Join Fetch" all OneToOne children.
    2. Enable the second level cache and use @Cache annotation on the OneToOne children.

    Your problem is that you didn't "join fetch" all of the OneToOne children. You must "join fetch" them all, including the transitive children (entities referenced from children themselves, or within the collection).

    Making OneToOne lazy (because its eager by default) is only partial solution, because hibernate will make a select for a child only when you access some getter on the child, but in long term it will still make all the N selects.

    0 讨论(0)
提交回复
热议问题