hibernate jpa: сессия закрыта! - PullRequest
       3

hibernate jpa: сессия закрыта!

0 голосов
/ 28 февраля 2011

Приложение основано на Spring 2.5.5 и Hibernate 3.2.0 GA.

У меня есть следующий метод в моем DAO, который подключает MessageEntities к указанному пользователю:

public MessageEntity findByUserId(int userId) {
      List<MessageEntity> result = (List<MessageEntity>) em.createNamedQuery(MessageEntity.Q_BY_USER_ID).setParameter("userId", userId).getResultList();
      if (!result.isEmpty()) {
         return result.get(0);
      } else {
         return null;
     }
}

Мне нужно вызвать этот метод из моего интеграционного теста, чтобы проверить правильность поведения системы. Пока этот метод не транзакционный, я получаю только org.hibernate.SessionException: Сессия закрыта! . Самый простой способ избежать этого - пометить метод findByUserId с помощью @ Transactional (readOnly = true) . Но, как я понимаю, управление транзакциями должно быть обязанностью уровня обслуживания, чтобы избежать ненужного создания транзакций. Итак, мой вопрос: как мне правильно уйти от SessionException ?

Ответы [ 3 ]

6 голосов
/ 28 февраля 2011

Вам нужно для выполнения всех ваших действий с базой данных в рамках транзакции. Как вы уже определили, он обычно считается хорошим дизайном, позволяющим сервисному уровню вашей модели базы данных иметь дело с транзакциями. Единственным ограничением становится то, что вы должны вызывать модель сервиса, чтобы попасть в область транзакции, что может быть нежелательно во время тестирования.

Я бы порекомендовал воспользоваться тестами , предоставленными spring. См 9.3.2.3 Управление транзакциями

Вы также можете вручную создать транзакцию перед проверкой вашего метода, например,

Session sess = factory.openSession();
Transaction tx = null;
// try catch 
tx = sess.beginTransaction();
findByUserId(userId);
tx.commit();
tx.rollBack();
1 голос
/ 28 февраля 2011

Поместите следующие аннотации в начало вашего тестового класса.

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")

Также я бы не стал беспокоиться о добавлении дополнительного @Transactional в DAO.Spring обычно проверяет, находится ли вы уже в транзакции (в том же потоке), прежде чем она создаст другую.

"Но, как я понимаю, управление транзакциями должно быть обязанностью уровня обслуживания, чтобы избежатьсоздание ненужных транзакций. "

Это скорее выбор дизайна (Spring Roo, например, нарушает это)

0 голосов
/ 19 марта 2015

Вы можете использовать эту аннотацию для вашего метода контроллера:

@Transactional(readOnly = true)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...