Hibernate транзакция не была успешно запущена - PullRequest
24 голосов
/ 01 марта 2011

Рассмотрим этот простой сценарий гибернации:

session = getHibernateSession();
tx = session.beginTransaction();
SomeObject o = (SomeObject) session.get(SomeObject.class, objectId);
tx.commit();

Этот код выдает следующее исключение:

org.hibernate.TransactionException: Transaction not successfully started
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:100)
    at com.bigco.package.Clazz.getSomeData(Clazz.java:1234)

Что происходит?

Ответы [ 5 ]

45 голосов
/ 01 марта 2011

Что ж, похоже, когда мы достигли линии tx.commit(), транзакция уже была совершена.Мое единственное предположение, что Hibernate уже фиксирует транзакцию, когда get() объект.

Исправить это просто:

// commit only if tx still hasn't been committed yet (by hibernate)
if (!tx.wasCommitted())
    tx.commit();
8 голосов
/ 18 ноября 2013

Это действительно старый вопрос, и я думаю, вы уже решили его (или отказались от Hibernate), но ответ трагически прост. Я удивлен, что никто другой не поднял это.

Вы еще не сделали session.save (o), поэтому в транзакции нет ничего для фиксации. Коммит может все еще не работать, если вы ничего не изменили в объекте, но зачем вам сохранять его, если ничего не изменилось?

Кстати: также вполне допустимо делать session.get (...) перед session.beginTransaction ().

6 голосов
/ 18 августа 2016

Я узнал, что это уже решено; хотя я публикую здесь свой ответ.

Я не нашел wasCommitted() метод транзакции.

Но у меня работал следующий код:

// commit only, if tx still hasn't been committed yet by Hibernate
if (tx.getStatus().equals(TransactionStatus.ACTIVE)) { 
    tx.commit();
}
0 голосов
/ 05 июля 2019

удалить session.close (); из вашей программы, так как немногие крупные транзакции требуют больше времени и при закрытии возникла проблема с подключением. использовать только session.flus ().

0 голосов
/ 22 ноября 2017

Одна из ситуаций, в которой это может произойти, - это когда код находится в EJB / MDB с использованием транзакций, управляемых контейнером (CMT), либо намеренно, либо потому, что он используется по умолчанию. Чтобы использовать транзакции, управляемые компонентом, добавьте следующую аннотацию:

@ TransactionManagement (TransactionManagementType.BEAN)

Это нечто большее, но это начало истории.

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