簡體   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