hibernate / spring пытается вставить, а не сохранить (запись уже существует в БД) после неудачной предыдущей транзакции - PullRequest
0 голосов
/ 31 марта 2011

У меня есть класс интерфейса пакета, который создает Hibernate Session, например:

Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));

Затем он вызывает службу для получения списка объектов из БД, а в классе пакета он выполняет итерациюlist и для каждого объекта он вызывает сервис, чтобы выполнить некоторую обработку объекта.

Скажем, на втором объекте где-то происходит какое-то исключение nullpointerexception, и я улавливаю исключение в своем пакетном классе.Затем я пытаюсь обработать 3-й объект и в сервисе, когда он пытается сохранить объект, вызывая HibernateDaoSupport.getSession (false) .save (object) - он фактически пытается вставить его (и я получаю ошибку, потому что запись ужесуществует) вместо обновления.

Это происходит только в случае сбоя предыдущего объекта.Если возникает исключение, делает ли он что-то с этим сеансом Hibernate?Любые идеи, что происходит?

У меня есть следующее в моем контексте context.xml

    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="*" rollback-for="Throwable"/>
    </tx:attributes>
</tx:advice>
<aop:config>
    <aop:pointcut id="serviceMethods" expression="execution(* com.company.service..*.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
</aop:config>

Ответы [ 2 ]

0 голосов
/ 31 марта 2011

Session.save должен присвоить идентификатор временному экземпляру и сохранить его, выполнив вставку. Я довольно удивлен, что он не делает этого в вашем первом сервисном звонке.

И поскольку в вашем служебном вызове возникает NPE, транзакция откатывается (поскольку вы настроили ее с <tx:method name="*" rollback-for="Throwable"/>), что может объяснить некоторые различия между последующими и ошибочными вызовами. Я не знаю, что должны делать ваши первые две строки кода, но, как сказал Божо, вам не следует связывать ресурсы с TransactionSynchronizationManager самостоятельно. Это ответственность весны.

0 голосов
/ 31 марта 2011

Пусть весна создаст ваш сеанс и будет управлять вашими транзакциями.TransactionSynchornizationManager - это то, что вы не должны обычно использовать.

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