JSF + Hibernate:集合未与任何会话关联 [英] JSF + Hibernate: Collection is not associated with any session

查看:175
本文介绍了JSF + Hibernate:集合未与任何会话关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我使用Java EE,将Hibernate与EntityManager和PrimeFaces结合使用.

First of all, I use Java EE, Hibernate with EntityManager and PrimeFaces.

我有一个EJB模块(业务逻辑和域)和两个WAR模块(Jersey WS和JSF PrimeFaces).

I have one EJB module (business logic and domain) and two WAR modules (Jersey WS and JSF PrimeFaces).

我决定在JSF WAR模块中初始化延迟集合,以避免延迟初始化异常.我不使用扩展实体管理器.

I decided to initialize lazy collections in JSF WAR module to avoid lazy initialization exception. I don't use extended entity manager.

@ManagedBean(name = "company")
@SessionScoped
public class CompanyBean {

    @EJB
    private CompanyFacade cf;

    ...

    public String showDetails(Long id) {
        company = cf.find(id);
        Hibernate.initialize(company.getCompanyTypes());
        Hibernate.initialize(company.getPrimaryUser());
        Hibernate.initialize(company.getBlocked());
        Hibernate.initialize(company.getAddresses());
        Hibernate.initialize(company.getContacts());
        return "DETAILS";
    }

    ...
}

然后我得到:

Caused by: org.hibernate.HibernateException: collection is not associated with any session at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:474) at org.hibernate.Hibernate.initialize(Hibernate.java:417) at minepackage.CompanyBean.showDetails(CompanyBean.java:79) ...

Caused by: org.hibernate.HibernateException: collection is not associated with any session at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:474) at org.hibernate.Hibernate.initialize(Hibernate.java:417) at minepackage.CompanyBean.showDetails(CompanyBean.java:79) ...

我不明白.从数据库中获取初始化之前的一行时,必须有一个会话,不是吗?我以类似的方式在WS模块中初始化属性,并且可以正常工作.

I don't understand it. There has to be a session when one line before the initialization it was fetched from database, doesn't it? I initialize attributes in WS module in similar way and there it's working.

知道发生了什么事吗?

推荐答案

我认为在EJB完成后会话关闭,因此对象处于 detached 状态.因此Hibernate.initialize()将不再起作用.您在这里有多种选择:

I think the session is closed after your EJB finished, so the objects are in detached state. So Hibernate.initialize() won't work any more. You have multiple options here:

  • 在客户端(在您的JSF bean或servlet过滤器中)打开事务.这样,当您呼叫Hibernate.initialize()时,会话仍将打开.
  • 修改您的EJB以加载完整的对象和所有必需的集合.您可以在其中使用访存联接和/或使用Hibernate.initialize().
  • 在EJB中创建更细粒度的API. CompanyFacade.getAddressesByCompany()之类的方法.
  • Open the transaction on the client side (in your JSF bean or in a servlet filter). This way the session will still be open when your are calling Hibernate.initialize().
  • Modify your EJB to load the full object and all the required collections. You could use fetch joins and/or use Hibernate.initialize() there.
  • Create a more fine grained API in your EJB. Method like CompanyFacade.getAddressesByCompany().

我希望将后两者结合起来.使用访存联接在find方法中加载一对一和多对一关系,并添加其他方法来加载一对多集合(如地址).因为它减少了数据库查询的次数,所以这也将提高后端的性能.

I would prefer a combination of the latter two. Use fetch joins to load the one-to-one and many-to-one relationships in your find method and add extra methods for loading the one-to-many collections (like addresses). This will also improve performance of your backend because it reduces the number of database queries.

这篇关于JSF + Hibernate:集合未与任何会话关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆