Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 弹簧&x2B;冬眠+;Postgresql只读事务,按需保存_Hibernate_Spring_Postgresql - Fatal编程技术网

Hibernate 弹簧&x2B;冬眠+;Postgresql只读事务,按需保存

Hibernate 弹簧&x2B;冬眠+;Postgresql只读事务,按需保存,hibernate,spring,postgresql,Hibernate,Spring,Postgresql,在这种非标准情况下,我需要更新只读Hibernate事务中的对象。问题是,我加载了许多其他对象,并在该事务中对它们进行了更改,但只应保存一个对象,其余对象将回滚。我使用的数据库是Postgresql 8.4 我不确定我是否正确理解文档,但制定服务方法: @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 应导致为该保存显式打开新的RW事务 主要是,这不起作用: @Transactional(readO

在这种非标准情况下,我需要更新只读Hibernate事务中的对象。问题是,我加载了许多其他对象,并在该事务中对它们进行了更改,但只应保存一个对象,其余对象将回滚。我使用的数据库是Postgresql 8.4

我不确定我是否正确理解文档,但制定服务方法:

@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)后,它工作正常,并保存在数据库中。谢谢!