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

时间:2016-10-08 05:07:30

标签: java spring hibernate one-to-many

我正在使用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<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;
...
}

我有一个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

有人可以帮忙解释一下吗?

1 个答案:

答案 0 :(得分:4)

  

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

发生这种情况的原因可能是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()。