Hibernate 弹簧&x2B;冬眠+;Postgresql只读事务,按需保存
在这种非标准情况下,我需要更新只读Hibernate事务中的对象。问题是,我加载了许多其他对象,并在该事务中对它们进行了更改,但只应保存一个对象,其余对象将回滚。我使用的数据库是Postgresql 8.4 我不确定我是否正确理解文档,但制定服务方法:Hibernate 弹簧&x2B;冬眠+;Postgresql只读事务,按需保存,hibernate,spring,postgresql,Hibernate,Spring,Postgresql,在这种非标准情况下,我需要更新只读Hibernate事务中的对象。问题是,我加载了许多其他对象,并在该事务中对它们进行了更改,但只应保存一个对象,其余对象将回滚。我使用的数据库是Postgresql 8.4 我不确定我是否正确理解文档,但制定服务方法: @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 应导致为该保存显式打开新的RW事务 主要是,这不起作用: @Transactional(readO
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
应导致为该保存显式打开新的RW事务
主要是,这不起作用:
@Transactional(readOnly = true)
public class PersonService {
@Resource(name="sessionFactory")
private SessionFactory sessionFactory;
public void add(Person person){
person.setFirstName("changed its name");
save(person);
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void save(Person person) {
Session session = sessionFactory.getCurrentSession();
session.save(person);
session.flush();
}
}
在那之后我得到了
org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常为org.hibernate.exception.genericjdbception:无法执行JDBC批更新
从控制器调用“add”方法add'处于只读模式,它将Person对象传递给save方法,该方法应打开新事务并保存到DB。在“add”方法的项目中,我加载了许多其他“Person”对象,这些对象不应保存。
我需要该方法为只读的原因是我在代码中加载了更多的对象:)回滚它们是我最不想做的事情
可以这样做吗?事务通常是通过生成服务接口的实现来应用的(您没有显示您正在实现一个接口,这可能只是您的示例代码?) 无论如何,关键是在这种情况下,简单地调用save(…)并不是通过包装器,而是在目标对象上运行方法。您需要将一个引用从服务注入到自身,这样它就可以调用自身并应用包装。即:
public class PersonServiceImpl implements PersonService {
PersonService personService;
public void readOnlyMethod() {
// ...
personService.readWriteMethod(...);
}
public void readWriteMethod(...) {
}
}
调用堆栈看起来像:
PersonServiceImpl.readWriteMethod(...)
TransactionAroundAdvice.advise(...) // starts/ends new read-write transaction
$Proxy.readWriteMethod(...) // implementing PersonService
PersonServiceImpl.readOnlyMethod(...)
TransactionAroundAdvice.advise(...) // starts/ends read-only transaction
$Proxy.readOnlyMethod(...) // implementing PersonService
ClientCode.doSomethingNotReallyReadOnly(...)
(您所描述的内容听起来像是记录了某种错误消息,这就是我使用requiresNew事务标记的地方(虽然在J2EE中,但我认为这一点是正确的))+1是的,这就是它不起作用的原因。在添加@Resource(name=“personService”)private personService personService并调用personService.save(person)后,它工作正常,并保存在数据库中。谢谢!