非法尝试将一个集合与两个打开的会话相关联-Dropwizard与Hibernate

问题描述 投票:1回答:1

我在我的dropwizard应用程序中使用Hibernate和JPA来帮助我的对象的CRUD操作。这是抛出异常的方法

@RetryOnFailure(attempts = 5,
      types = {org.hibernate.exception.LockTimeoutException.class,
          org.hibernate.exception.LockAcquisitionException.class},
      delay = DATABASE_RETRY_DELAY_SECONDS, unit = TimeUnit.SECONDS)
  public MyObject createOrSave(MyObject myObject) {

    Session session = sessionFactory.openSession();



    session.beginTransaction();
    try {

      session.saveOrUpdate(service);
      session.getTransaction().commit();
    } catch (RuntimeException e) {

      session.getTransaction().rollback();
      throw e;
    } finally {

      if (session != null && session.isOpen()) {
        session.close();
      }
    }
    return myObject;
  }

SO上有很多线程可以解决这个问题,到目前为止我已经尝试过了

  • 检查会话是否打开,如果是,使用session.getCurrentSession(),这会引发错误“transaction is already active
  • 根本不要使用交易
  • 检查数据库中是否存在记录,如果是,请使用session.merge() else session.save()
  • 在我的关系中不要使用qazxsw poi,但这导致了“qazxsw poi”

我是出于想法,有什么想法吗?

看一下这个问题,似乎问题是与MyObject上的Element集合的关系被声明为

CascadeType.ALL

有没有其他方法来声明这样,以便在保存或更新myObject时可以修改它?

所以我将映射更改为

trying to refernece transient object error

这摆脱了这个特定映射的错误,但我仍然得到了

  @JsonIgnore
  @Column
  @ElementCollection(targetClass = Long.class)
  Set<Long> someLongIds;

对象上所有其他映射的错误。

这是因为该集合是一个集合?而不是线程安全?

hibernate session jpa dropwizard
1个回答
0
投票

听起来Hibernate中有两个打开的Sessions,而MyObject正在从一个传递到另一个。

最简单的解决方案通常是使用相同的 @JsonIgnore @Column @ElementCollection(targetClass = Long.class, fetch = fetchType.Lazy) Set<Long> someLongIds; 。如果使用JTA事务(或Hibernate中的任何其他形式的Illegal attempt to associate a collection with two open sessions. Collection ),可以通过调用Session找到它。显然,这在多线程环境中是行不通的。

另一条路线是分离contextual sessions。回到第一个Session(问题中没有显示),当从数据库中检索到sessionFactory.getCurrentSession()时,它也可以从该会话中分离出来:

myObject

这具有解决myObjectsession.detach(myObject); 的效果,因此可以在会话之外访问,或者在另一个会话中访问它们。

© www.soinside.com 2019 - 2024. All rights reserved.