Подтвердить что ты не робот

Не удалось запустить транзакцию спящего режима

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

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)

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

4b9b3361

Ответ 1

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

Исправление для этого просто:

// commit only if tx still hasn't been committed yet (by hibernate)
if (!tx.wasCommitted())
    tx.commit();

Ответ 2

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

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

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

Ответ 3

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

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

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

// commit only, if tx still hasn't been committed yet by Hibernate
if (tx.getStatus().equals(TransactionStatus.ACTIVE)) { 
    tx.commit();
}

Ответ 4

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

@TransactionManagement (TransactionManagementType.BEAN)

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

Ответ 5

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