3

我们目前正在从 JavaEE5 迁移到 JavaEE6,并且正在使用 JBoss 6.0.0 和 JSF2。为简单起见,此示例是基于 Maven 原型构建的:org.jboss.weld.archetypes:jboss-javaee6-webapp:1.0.1.CR2

我添加了一个简单的 LAZY 关系User

@NotNull @ManyToMany(fetch=FetchType.LAZY)
private List<Address> addresses;

这个 bean 是 maven 原型的一部分,我在retrieveAllMembersOrderedByName().

@RequestScoped
public class MemberListProducer {
    @Inject private Logger log;

    @Inject @MemberRepository
    private EntityManager em;

    private List<Member> members;

    @Produces  @Named
    public List<Member> getMembers(){return members;}

    @PostConstruct
    public void retrieveAllMembersOrderedByName()
    {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
        Root<Member> member = criteria.from(Member.class);
        criteria.select(member).orderBy(cb.asc(member.get("name")));
        members = em.createQuery(criteria).getResultList();

        Member m1 = members.get(0);
        log.info("Id: "+m1.getId());

        Member m2 = em.find(Member.class, m1.getId());

        log.info("Addr m1: "+m1.getAddresses().size());  // OK
        log.info("Addr m2: "+m2.getAddresses().size());  // Error
    }}

如您所见,List<Member>由 CriteriaQuery 检索,然后Member m1从 List 中获取并Member m2从相同的EntityManager em. 现在有趣的部分:m1.getAddresses().size()工作,m2.getAddresses().size()给出一个

    15:41:32,910 ERROR [org.hibernate.LazyInitializationException]
failed to lazily initialize a collection of role: test.Member.addresses,
no session or session was closed: org.hibernate.LazyInitializationException:
failed to lazily initialize a collection of role:test.Member.addresses,
no session or session was closed

谁能解释一下,或者知道如何解决这个问题?谢谢你,托尔

4

3 回答 3

0

您可以通过下面给出的具有默认延迟初始化的代码动态获取相关对象:

criteria.setFetchMode("地址", FetchMode.JOIN);

于 2011-08-17T10:19:49.307 回答
0

托尔,你能再检查一下吗?我认为这很有趣并自己尝试过,但是我在两次通话中都遇到了异常。它们都不起作用。我可能做错了什么,但我检查了几次,两种方法都给了我这个例外。你让记录器记录第一个集合的大小吗?

于 2011-07-18T09:20:42.930 回答
0

这是延迟加载的正常行为,所有延迟类都是代理。当您从代理获取类时,您的 Hibernate 会话已经关闭。

解决方案是在 View Filter 中实现 Open Session,这将使您的 Hibernate 会话保持打开状态,直到您的请求处于活动状态。

您可以在本文中阅读更多相关信息

http://community.jboss.org/wiki/OpenSessionInView

如果您使用的是 Spring Framework,那么您已经完成了这个工作OpenSessionInViewFilter类。

希望能帮助到你。

于 2011-06-06T14:46:06.433 回答