Hibernate many to many - fetch method eager vs lazy

后端 未结 2 606
终归单人心
终归单人心 2020-12-16 02:42

New to Hibernate.

I have User Group many to many relation. Three tables : User , Group and UserGroup mapping table.

Entities:

@Entity
@Table(         


        
2条回答
  •  清歌不尽
    2020-12-16 03:22

    Although answer from JamesENL is almost correct, it is lacking of some very key aspect.

    What he is doing is to force the lazy-loading proxy to load when the transaction is still active. Although it solved the LazyInitialization error, the lazy loadings are still going to be done one by one, which is going to give extremely poor performance. Essentially, it is simply achieving the same result of FetchType.EAGER manually (and with a even worse way, because we missed the possibilities of using JOIN and SUBSELECT strategy), which even contradict with the concern of performance.

    To avoid confusion: Using LAZY fetch type is correct.

    However, in order to avoid Lazy Loading Exception, in most case, you should have your repository (or DAO?) fetch the required properties.

    The most inefficient way is to do it by accessing the corresponding property and trigger the lazy loading. There are some really big drawbacks:

    1. Imagine what happen if you need to retrieve multiple level of data.
    2. If the result set is going to be big, then you are issuing n+1 SQLs to DB.

    The more proper way is to try to fetch all related data in one query (or a few).

    Just give an example using Spring-data like syntax (should be intuitive enough to port to handcraft Hibernate Repository/DAO):

    interface GroupRepository {
        @Query("from Group")
        List findAll();
    
        @Query("from Group g left join fetch g.users")
        List findAllWithUsers();
    }
    

    Join fetching is equally simple in Criteria API (though seems only left join is available), quoted from Hibernate doc:

    List cats = session.createCriteria(Cat.class)
        .add( Restrictions.like("name", "Fritz%") )
        .setFetchMode("mate", FetchMode.EAGER)
        .setFetchMode("kittens", FetchMode.EAGER)
        .list();
    

提交回复
热议问题