2014-09-30 158 views
4

我在我的應用程序中使用spring和hibernate並使用spring事務。hibernate session.flush with spring @transactional

所以我有服務層註釋@transaction方法和DAO層有數據庫查詢方法。

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

} 

的問題是,當我要保存一個對象在數據庫中,然後我在DAO層method.Why結束使用session.flush()

我想如果我有註解@事務,那麼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); 
    } 

Spring配置:

<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"/> 
+1

春天爲你做,'readonly = false'是默認的,你沒有聲明 – Jaiwo99 2014-09-30 12:53:06

+0

我認爲自動提交併不打算立即刷新'Session'到數據庫,但是在該事務中完成的更改可用於使用同一'Session'的其他事務。 – 2014-09-30 12:55:21

+1

如果你會正確設置交易,那麼是的......但是你的設置是有缺陷的。你爲什麼同時使用'SessionFactory'和'EntitymanagerFactory'?您只使用單個事務管理器。主要問題是你的設置。 – 2016-10-25 12:40:20

回答

0

是的,如果你有@Transactional你的DAO方法,那麼你不需要刷新會話,hibernate將負責刷新會話作爲提交的一部分如果方法中的操作成功,則進行交易。

檢查此鏈接瞭解有關@Transactional如何工作 - Spring - @Transactional - What happens in background?

+0

謝謝,但沒有session.flush,更新不反映在數據庫中,我錯過了什麼? – 2014-10-01 05:20:44

+1

我沒有找到你,你能詳細說明你的意思嗎? – Chaitanya 2014-10-01 05:34:27

+0

如果我不在dao層中寫session.flush,那麼記錄不會在數據庫中保存,因爲我在服務層使用@transactional,那麼是否存在任何配置問題或其他問題? – 2014-10-01 06:41:41

0

默認情況下,休眠棧的查詢,以便他們可以當他們終於到數據庫執行進行優化。

flush的缺點是刷新這個堆棧,並在事務中執行它到數據庫中。你離開jvm的「保存」房屋,然後在一個很奇怪的數據庫上執行你的查詢。

這就是爲什麼你不能選擇你沒有刷新保存的東西。它根本不在數據庫中。

提交的含義是一旦交易結束,並使數據庫的更改可見其他人。一旦執行提交,就不可能有任何回報。

坦率地說,我不確定這是否是最佳做法,但對於正常的CRUD操作,您應該可以將刷新添加到您的dao圖層中。 這樣你就不用擔心它進入服務層。

如果您希望java優化您的交易,那麼您必須將其添加到您的服務層。但請記住,當沒有任何問題時,您不需要解決性能問題!將代碼全部刷新到服務層中對代碼可讀性不利。保持簡單和愚蠢;)

相關問題