java - 显式 EntityManager.find 后 @RequestScoped Bean 中的 LazyInitializationException

标签 java hibernate jboss lazy-loading jboss6.x

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

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

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

这个 bean 是 maven 原型(prototype)的一部分,我在 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取自列表和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

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

最佳答案

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

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

您可以在这篇文章中阅读更多相关信息

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

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

希望对您有所帮助。

关于java - 显式 EntityManager.find 后 @RequestScoped Bean 中的 LazyInitializationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6253358/

相关文章:

java - [Microsoft][SQLServer 2000 Driver for JDBC]登录已超时

java - 我做错了什么,hibernate/spring Boot 显示来自 mysql 的名称

java - EJB 升级到 JBoss AS 7 时出错

jboss - 如何使用模块将库添加到 Wildfly Application Server?

java - 有什么方法可以模拟 HTTP 错误响应 5xx 和 4xx

java - 我应该使用复合主键吗?

java - 当变量被声明为具有函数作用域时,我收到类型错误

java - 寻找累积频率数组

java - 现有数据库上的飞路迁移导致 "wrong column type encountered in column"

java - Spring 启动 Jpa : hibernate as default?