Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 939
seaguest Avatar asked Oct 08 '16 05:10

seaguest


1 Answers

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().

like image 199
ujulu Avatar answered Oct 22 '22 16:10

ujulu