除非访问集合,否则Hibernate OneToMany FetchType.LAZY无法正常工作?

我使用spring 4.1.4.RELEASE + hibernate 4.3.6.Final,这是我的实体代码:

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 channelGroups; public List getChannelGroups() { return channelGroups; } public void setChannelGroups(List 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; ... } 

我有一个MarketInfo,我希望当我调用它的getChannelGroups()方法时,它会返回List,但是我可以看到在这种情况下没有触发HQL查询,似乎我们必须访问该List中的一些项来触发HQL查询,否则,MarketInfo的channelGroups为空。

情况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 

案例2:

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

案例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 

谁能帮忙解释一下?

market.getChannelGroups(); //这不起作用,市场的channelGroups仍然是空的。

发生这种情况的原因可能是market.getChannelGroups()调用由于延迟加载而返回代理 。 当您在返回的对象上调用方法时会发生实际加载,在这种情况下,该方法是通道组集合。 因此,要触发将实体加载到集合中,您必须调用以下内容,例如:

 market.getChannelGroups().size(); 

现在为什么以下呼叫有效?

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

如果您了解System.out.println()是如何工作的原因将是明确的,即它在传入的对象上调用toString()方法,在这种情况下等效于以下内容:

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

这是println(Object)方法的JavaDoc:

打印一个对象,然后终止该行。 此方法首先调用String.valueOf(x)来获取打印对象的字符串值,然后表现为调用print(String)然后调用println()。