Hibernate OneToMany FetchType.LAZY is not working unless accessing the collection?

徘徊边缘 提交于 2019-12-07 09:51:24

问题


I am using spring 4.1.4.RELEASE + hibernate 4.3.6.Final, here is my entity code:

public class BaseEntity implements Serializable {
}

public class MarketInfo extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @Column(name = "market_id", unique = true, length = 15)
    private String marketId;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "market")
    private List<MarketChannelGroup> channelGroups;

    public List<MarketChannelGroup> getChannelGroups() {
        return channelGroups;
    }

    public void setChannelGroups(List<MarketChannelGroup> channelGroups) {
        this.channelGroups = channelGroups;
    }

...
}

public class MarketChannelGroup extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "market_id", referencedColumnName = "market_id")
    private MarketInfo market;
...
}

I have a MarketInfo, I expect that when I call its getChannelGroups() method, it will return List, however I can see HQL query is not triggered in this case, it seems that we must access some item inside that List to trigger the HQL query, otherwise, MarketInfo's channelGroups is null.

Case 1:

System.out.println(market.getChannelGroups()); // this is working, market's channelGroups is not empty. HQL query is triggered.

// here market's channelGroups is not empty

Case 2:

market.getChannelGroups(); // this is not working, market's channelGroups is still empty.HQL query is not triggered.

// here market's channelGroups is empty

Case 3:

market.getIndexes().get(0).getDate(); // this is working, market's channelGroups is not empty. HQL query is triggered.

// here market's channelGroups is not empty

Could anyone help explain?


回答1:


market.getChannelGroups(); // this is not working, market's channelGroups is still empty.

The reason why this is happening might be the market.getChannelGroups() call is returning a proxy because of the lazy loading. The actual loading will happen when you call a method on the returned object which in this case is channel groups collection. So to trigger the loading of the entities into the collection you have to call the following, for example:

market.getChannelGroups().size();

Now why is the following call working?

System.out.println(market.getChannelGroups());

The reason will be clear if you understand how System.out.println() is working, namely, it is calling the toString() method on the passed in object which in this case is equivalent to the following:

System.out.println(market.getChannelGroups().toString());

Here is the JavaDoc for the println(Object) method:

Prints an Object and then terminate the line. This method calls at first String.valueOf(x) to get the printed object's string value, then behaves as though it invokes print(String) and then println().



来源:https://stackoverflow.com/questions/39928888/hibernate-onetomany-fetchtype-lazy-is-not-working-unless-accessing-the-collectio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!