org.springframework.transaction.UnexpectedRollbackException для пустого столбца @Version - PullRequest
1 голос
/ 06 ноября 2010

Я использую Spring 3.0.4-RELEASE, JPA 2.0 с Hibernate в качестве провайдера и JTA JOTM для транзакций в моем приложении. Я получил следующую ошибку при вызове entityManager.merge объекта моего объекта:

org.objectweb.jotm.SubCoordinator commit_one_phase
INFO: Rollback during beforeCompletion in SubCoordinator.commit_one_phase
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException 
      at
 org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1012)    

Эта ошибка возникла в результате вставки данных непосредственно в базу данных (MySQL) через нашу работу Talend ETL. Я заметил, что мой столбец @Version в базе данных имеет значения NULL, и решил установить для них значение 0, и это решило проблему.

Почему столбец @Version не может быть NULL? Кто-нибудь еще сталкивался с этой проблемой? Спасибо.

Ответы [ 2 ]

1 голос
/ 07 ноября 2010

Я получил следующую ошибку при вызове entityManager.merge для моего объекта-сущности

Если вы хотите полностью понять, что здесь происходит, активируйте ведение журнала, чтобы точно увидеть, что в результатев RollbackException (подозреваю, «плохой» SQL).

Обратите внимание, что вы не получаете OptimisticLockException, я думаю, что Hibernate каким-то образом запутывается версией NULL.Я на самом деле не копал проблему и не могу объяснить ее в деталях, но кажется, что Hibernate даже не генерирует ожидаемый оператор UPDATE для слияния.

Почему не может @Версия столбца будет NULL?Кто-нибудь еще сталкивался с этой проблемой?Спасибо.

Как я уже писал, я не могу дать точную причину, но у меня возникает соблазн ответить: потому что это не значение, ожидаемое Hibernate.Hibernate начинался бы с 0 в качестве начального значения для столбца версии, поэтому я хотел бы учитывать ожидания Hibernate и установить его в качестве значения по умолчанию.

Если вы хотите понять, почему установка NULL в качестве начального значениявызывая проблемы, вам придется отлаживать код Hibernate.Но, честно говоря, это звучит как пустая трата времени: поскольку вы используете Hibernate, просто уважайте / имитируйте поведение Hibernate, обходя API Hibernate.

0 голосов
/ 06 ноября 2010

Какое поведение вы ожидаете?

При выполнении merge для отсоединенного объекта выдается исключение оптимистичного параллелизма, если версия отсоединенного объекта не соответствует версии в базе данных. Я полагаю, в вашем случае это исключение заключено в UnexpectedRollbackException. Если версия отдельного объекта - 0, установка столбца версии в базе данных на 0 решает эту проблему.

Реальным решением было бы увеличение версии объекта в базе данных, когда внешнее программное обеспечение изменяет его. Это будет соответствовать оптимистичной стратегии блокировки.

...