Vaadin 中的休眠会话错误

Posted

技术标签:

【中文标题】Vaadin 中的休眠会话错误【英文标题】:Hibernate session error in Vaadin 【发布时间】:2014-10-16 14:00:39 【问题描述】:

我正在使用 JPAContainer 和 hibernate 4.3 开发 Vaadin 网络应用程序。 我按照link 的说明成功实现了 EntityManager-per-Request 模式。这意味着延迟加载适用于 JPAContainer

但是,每次我需要使用纯 JPA 时,它都无法延迟加载。

这是一个示例代码:

 try 
    entityManagerProvider.getEntityManager().getTransaction().begin();

    List<SubEntity> subEntitiesList = myEntity.getCollectionOfEntities(); //Fails to load

    for (SubEntity subEntity : subEntitiesList) 
        subEntity.doSomething();
        entityManagerProvider.getEntityManager().merge(subEntity);
    
    entityManagerProvider.getEntityManager().flush();
    entityManagerProvider.getEntityManager().getTransaction().commit();
 catch (Exception ex) 
    entityManagerProvider.getEntityManager().getTransaction().rollback();


//datasource is JPAContainer<MyEntity>  type
datasource.removeItem(index);

我已经尝试过这个解决方案:

    使用 hibernate.enable_lazy_load_no_trans 它自动打开了一个会话,但它给出了一个严重的警告:

    “无法关闭用于加载与无会话关联的惰性集合的临时会话”

另外,当我从 JPAContainer 中删除实体时,我收到一个错误:org.hibernate.PersistentObjectException: detached entity passing to persist

谁能给我一些关于如何处理这个问题的提示?

【问题讨论】:

【参考方案1】:

我看到了两种方法。

将分离实体的变化合并到数据库中

只需合并实体,对托管值进行操作即可。

Entity managed = em.merge(entity);

for (SubEntity sub : managed.getSubEntities()) 
    sub.doSomething();

在不接触数据库的情况下解决惰性代理

通过 ID 查找实体并将属性复制到分离的实体。

Entity managed = em.find(entity.getClass(), entity.getId());
entity.setSubEntities(managed.getSubEntities());

对于第二个选项,我编写了一个通用实用程序方法来将分离的实体初始化到一定深度 也许你会觉得它很有用。

// initialize lazy collections and collection elements
JpaUtils.initialize(em, entity, 2);

源代码见JpaUtils。

【讨论】:

谢谢何塞!很好的答案!最后一个问题:使用第二种方法,如果我使用 em.getReference 而不是 em.find 会怎样? @guilhermecgs 没关系,特别是如果你只想初始化一些属性。

以上是关于Vaadin 中的休眠会话错误的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 Spring Security 的 Vaadin 出现 403 CSRF 令牌错误

Grails 3.0.1 和休眠会话错误

带有 2 个数据库的休眠随机“会话已关闭错误”

异常 ORA-00942: 表或视图不存在 - 使用休眠会话插入现有表时

会话会话= sessionFactory.openSession();是不是在休眠

Spring和休眠:没有为当前线程找到会话