LazyLoadingException,Hibernate.initialize,FetchMode,MultipleBags

时间:2014-08-26 12:22:51

标签: hibernate

想象一下这种关系,其中一只股票有很多类别。

库存

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "stock_category" , joinColumns = { 
        @JoinColumn(name = "STOCK_ID", nullable = false, updatable = false) }, 
        inverseJoinColumns = { @JoinColumn(name = "CATEGORY_ID", 
                nullable = false, updatable = false) })
public Set<Category> getCategories() {
    return this.categories;
}

分类

 @ManyToMany(fetch = FetchType.LAZY, mappedBy = "categories")
public List<Stock> getStocks() {
    return this.stocks;
}

当我尝试列出所有类别和您的股票时,我得到了延迟加载例外 - 没有会话或会话被关闭。

所以我改变了我的方法来初始化每个类别的所有股票。如果我想初始化另一个实体,我只需将其放入循环中:

 session = HibernateUtil.getSessionFactory().openSession();
            Criteria cri = session.createCriteria(Category.class)
                     .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

            List<Category> categories = (List<Category>) cri.list();

            for (Category c :categories) {
                Hibernate.initialize(c.getStocks()); 
            } 

但我为每个类别获得了一个初始化股票的SQL,我认为这不好。

所以,我尝试使用.setFetchMode(“stocks”,FetchMode.JOIN),我将获得一个SQL,但如果我想使用fecthmode并需要加入另一个实体,我将“无法同时获取多个袋”。

产品

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "product_category" , joinColumns = { 
        @JoinColumn(name = "PRODUCT_ID", nullable = false, updatable = false) }, 
        inverseJoinColumns = { @JoinColumn(name = "CATEGORY_ID", 
                nullable = false, updatable = false) })
public Set<Category> getCategories() {
    return this.categories;
}

列表:

session = HibernateUtil.getSessionFactory().openSession();
            Criteria cri = session.createCriteria(Category.class)
                     .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                     .setFetchMode("stocks", FetchMode.JOIN)
                     .setFetchMode("products", FetchMode.JOIN);

我不相信使用hibernate这是最好的方法。我读了很多关于OpenSessionInView的内容,但有些人认为这是一个糟糕的模式。

1 个答案:

答案 0 :(得分:2)

因此,我了解您的Category实体与实体ManyToMany以及Stock之间存在Product关系。在Category实体中,如果您尝试将List用于属性stocks amd products,然后如果要将获取模式设置为JOIN,则:

`criteria.setFetchMode("stocks", FetchMode.JOIN).setFetchMode("products", FetchMode.JOIN);`

然后Hibernate抛出异常:

 org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

要解决此问题,您必须更改stocks&amp;的属性类型。您products实体类中的SetList而不是Category