Недопустимая попытка связать коллекцию с двумя открытыми сеансами - PullRequest
0 голосов
/ 17 сентября 2018

Я использую Hibernate и JPA в своем приложении dropwizard, чтобы помочь с 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()
  • В моих отношениях не используйте CascadeType.ALL, но это привело к "trying to refernece transient object error"

У меня нет идей, есть идеи?

Если взглянуть больше на это, похоже, проблема в связи с коллекцией элементов в MyObject, которая объявлена ​​как

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

Есть ли другой способ объявить это, чтобы его можно было изменитькогда myObject сохраняется или обновляется?

Поэтому я изменил отображение на

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

Это избавило от ошибки для этого конкретного отображения, но я все еще получаю

Illegal attempt to associate a collection with two open sessions. Collection

ошибка на всех других сопоставлениях на Объекте.

это потому, чтоКоллекция - это Набор?а не нить безопасна?

1 Ответ

0 голосов
/ 15 февраля 2019

Похоже, что в Hibernate есть две открытые сессии, и MyObject передается от одной к другой.

Обычно самое простое решение - использовать одну и ту же Session.Если вы работаете с транзакциями JTA (или любой другой формой контекстных сессий в Hibernate), это можно узнать, вызвав sessionFactory.getCurrentSession().Очевидно, что это не будет работать в многопоточной среде.

Другой путь - отключить myObject.В первом сеансе (не показан в вопросе), когда myObject был извлечен из базы данных, он также может быть отсоединен от этого сеанса:

session.detach(myObject);

Это имеет эффект разрешения PersistentSet из someLongIds, чтобы к ним можно было получить доступ вне сеанса или в равной степени в другом сеансе.

...