繁体   English   中英

hibernate session.flush with spring @transactional

[英]hibernate session.flush with spring @transactional

我在我的应用程序中使用spring和hibernate并使用spring事务。

所以我在方法和带有数据库查询方法的DAO层上有注释@transaction的服务层。

@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);
    }

弹簧配置:

<context:property-placeholder properties-ref="deployProperties" />

    <tx:annotation-driven transaction-manager="transactionManager" />   

    <!-- Activate Spring Data JPA repository support -->
    <jpa:repositories base-package="com" />

    <!-- Declare a datasource that has pooling capabilities-->   
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close"
        p:driverClass="${app.jdbc.driverClassName}"
        p:jdbcUrl="${app.jdbc.url}"
        p:user="${app.jdbc.username}"
        p:password="${app.jdbc.password}"
        p:acquireIncrement="5"
        p:idleConnectionTestPeriod="60"
        p:maxPoolSize="100"
        p:maxStatements="50"
        p:minPoolSize="10" />

    <!-- Declare a JPA entityManagerFactory -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
        p:persistenceXmlLocation="classpath*:META-INF/persistence.xml"
        p:persistenceUnitName="hibernatePersistenceUnit"
        p:dataSource-ref="dataSource"
        p:jpaVendorAdapter-ref="hibernateVendor"/>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
        p:dataSource-ref="dataSource" p:configLocation="${hibernate.config}"
        p:packagesToScan="com" />

    <!-- Specify our ORM vendor -->
    <bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
                p:showSql="false"/>

    <!-- Declare a transaction manager-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
        p:entityManagerFactory-ref="entityManagerFactory"/>

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

查看此链接以了解@Transactional的工作原理 - Spring - @Transactional - 后台会发生什么?

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

刷新的漏洞是刷新此堆栈并在事务中将其执行到数据库中。 你离开jvm的“保存”房子并在一个大的奇怪的数据库上执行你的查询。

这就是为什么你不能选择你刚刚保存而没有同花顺的东西。 它根本就不在数据库中。

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

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

如果您希望java优化您的交易,那么您必须将其添加到您的服务层。 但请记住,在没有任何问题时你不需要解决性能问题! 将所有代码刷新到服务层不利于代码可读性。 保持简单和愚蠢;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM