Java hibernate session.flush with spring@transactional

Java hibernate session.flush with spring@transactional,java,spring,hibernate,spring-transactions,Java,Spring,Hibernate,Spring Transactions,我在应用程序中使用Spring和Hibernate,并使用Spring事务 因此,我有一个服务层,在方法上有注释@Transaction,DAO层有用于数据库查询的方法 @Transactional(readOnly = false) public void get(){ } 问题是,当我想在数据库中保存一个对象时,我必须在DAO层方法的末尾使用session.flush()。为什么? 我认为如果我已经注释了@Transaction,那么Spring应该在服务方法完成时自动提交事务 DAO层

我在应用程序中使用Spring和Hibernate,并使用Spring事务

因此,我有一个服务层,在方法上有注释
@Transaction
,DAO层有用于数据库查询的方法

@Transactional(readOnly = false)
public void get(){

}
问题是,当我想在数据库中保存一个对象时,我必须在DAO层方法的末尾使用
session.flush()
。为什么?

我认为如果我已经注释了
@Transaction
,那么Spring应该在服务方法完成时自动提交事务

DAO层:

public BaseEntity saveEntity(BaseEntity entity) throws Exception {
        try {
            Session session = sessionFactory.getCurrentSession();
            session.saveOrUpdate(entity);
            session.flush();
        } catch (HibernateException he) {
            throw new Exception("Failed to save entity " + entity);
        }
        return entity;
    }
服务层:

    @Transactional(readOnly = false)
    public BaseEntity saveEntity(BaseEntity entity) throws Exception {
        return dao.saveEntity(entity);
    }
弹簧配置:


是,如果DAO方法具有
@Transactional
,则不需要手动刷新会话,如果方法中的操作成功,hibernate将负责刷新会话作为提交事务的一部分


查看此链接以了解@Transactional是如何工作的-

默认情况下,hibernate将其查询堆叠起来,以便在最终将查询执行到数据库时对其进行优化

刷新的关键是刷新这个堆栈,并在数据库的事务中执行它。您将离开jvm的“保存”之家,在一个奇怪的大数据库上执行查询

这就是为什么在没有刷新的情况下不能选择刚保存的内容。它根本不在数据库中

commit的意思是结束一次事务并使数据库的更改对其他人可见。一旦执行了提交,就不可能再返回了

坦白地说,我不确定这是否是一个最佳实践,但对于正常的CRUD操作,您应该能够将flush添加到dao层中。 这样,您就不必担心它会进入服务层


如果希望java优化事务,那么必须将其添加到服务层中。但请记住,当没有性能问题时,您不需要解决性能问题!将所有代码刷新到服务层对代码可读性没有好处。保持简单和愚蠢;)

spring为您执行此操作,默认情况下,
readonly=false
,您不必声明itI,我认为自动提交并不打算立即将
会话
刷新到DB,但是,使该事务中所做的更改可用于使用同一
会话的其他事务。如果您希望正确设置事务,则是。。。但是你的设置有缺陷。为什么要同时使用
会话工厂
实体管理工厂
?您只使用一个事务管理器。主要问题是您的设置。是的,同意@M.Deinum,您使用的SessionFactory与Spring TransactionManager无关。所以,spring没有在您的设置中处理事务。谢谢,但是没有会话。刷新,更新没有反映在数据库中,我是不是遗漏了什么?我没有理解您的意思,您能详细说明一下您的意思吗?如果我没有在dao层中编写session.flush,则记录不会保存在数据库中,而它应该保存在数据库中,由于我在服务层中使用@transactional,所以是否存在任何配置问题或其他问题?Spring应该负责刷新会话和提交事务。似乎您在DAO层本身做了一些错误的事情,您是否可以添加DAO层中的代码,然后我们就可以了解问题的原因了。DAO层中的
sessionFactory
仅由Spring注入?