Не удалось запустить транзакцию спящего режима
Рассмотрим этот простой сценарий спящего режима:
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)
Что происходит?
Ответы
Ответ 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().