Я использую Spring и Hibernate, пытаясь обновить значение в базе данных. Это необходимо, чтобы в случае возникновения исключений сохранить сообщение об ошибке в таблице. Я столкнулся с некоторыми ошибками, потому что, когда я могу сохранить сообщение в базе данных, транзакция не откатывается. Вот псевдокод
@Transactional
public class ObjectTable(){
//instanciate other objects
RelatedObject relatedObject = relatedObjectController.getObjectById(primaryKey)
Object object = objectController.getObjectByRelatedObject(relatedObject.getPrimaryKey())
@Transactional(rollbackFor = Exception.class)
public updateObject(Object object) throws MyCustomException{
try{
getHibernateTemplate().getSessionFactory.getCurrentSession().evict(object);
getHibernateTemplate().getSessionFactory.getCurrentSession().saveOrUpdate(object);
getSession.flush();
}catch(Exception ex){
saveErrorMessageIntoDatabase(ex.getMessage, this.relatedObject);
throw new MyCustomException(ex.getMessage)
}
}
public saveErrorMessageIntoDatabase(String message, RelatedObject relatedObject){
relatedObject.setErrorMessage(message);
getHibernateTemplate().getSessionFactory.getCurrentSession().evict(relatedObject);
getHibernateTemplate().getSessionFactory.getCurrentSession().saveOrUpdate(relatedObject);
getSession.flush();
}
}
При таком подходе я не могу сохранить сообщение в relatedObject
и откатить изменения в object
. Сделав несколько вариантов, таких как добавление propagation = Propagation.REQUIRES_NEW
или propagation = Propagation.REQUIRED
или удаление Excpection.class для отката, я получаю некоторые другие варианты поведения, например, сохраняю сообщение об ошибке, но также записываю изменения object
, когда возникает исключение. , или откатить изменения, но не записать сообщение об ошибке в relatedObject
.
Я также пробовал с merge
вместо saveOrUpdate
, но безуспешно.
Может кто-нибудь помогите мне написать способ отката изменений в случае ошибки, но также сохранить сообщение об ошибке в базе данных?
Спасибо.
* Я не публикую фактический код, потому что это не личный проект.
РЕДАКТИРОВАТЬ: Мой transactionManager
настроен как XML bean, где сначала я создаю objectTableTarget
, устанавливая свойство sessionFactory
, а ниже я устанавливаю другой bean objectTable
, ссылаясь на методы, которые я хочу сделать транзакционными.
<bean id="objectTableTarget" class="br.com.classes.ObjectTable" singleton="true">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="objectTable" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager" />
<property name="target" ref="objectTableTarget" />
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
<prop key="updateObject*">PROPAGATION_REQUIRED,-br.com.package.exception.MyCustomException</prop>
</props>
</property>
</bean>