2014-03-29 16 views
0

我必須保留在@Transactional控制器中打開的ResultSet,以便在MessageConverter內使用。在會話工廠豆防止在事務提交時關閉ResultSet

<mvc:interceptors> 
    <bean class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor" 
     p:sessionFactory-ref="sessionFactory"/> 
</mvc:interceptors> 
  • <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" 
        <property name="hibernateProperties"> 
        <props> 
         <prop key="hibernate.connection.release_mode">on_close</prop> 
         .... 
        </props> 
        </property> 
    </bean> 
    
  • 控制器方法中:

    session.doWork((con) -> { con.setHoldability(HOLD_CURSORS_OVER_COMMIT); }); 
    
  • 爲此我已經配置了以下內容:

    1. MVC攔截

    然而PSQLException: This ResultSet is closed.仍然存在。這是在日誌中有關片段在交易時控制方法的返回承諾:

    TRACE o.h.e.j.i.JdbcCoordinatorImpl - Registering result set [[email protected]] 
    DEBUG o.h.e.t.s.AbstractTransactionImpl - committing 
    TRACE o.h.internal.SessionImpl - Automatically flushing session 
    TRACE o.h.internal.SessionImpl - before transaction completion 
    DEBUG o.h.e.t.i.j.JdbcTransaction - committed JDBC Connection 
    DEBUG o.h.e.t.i.j.JdbcTransaction - re-enabling autocommit 
    TRACE o.h.e.t.i.TransactionCoordinatorImpl - after transaction completion 
    TRACE o.h.internal.SessionImpl - after transaction completion 
    TRACE o.h.internal.SessionImpl - Setting flush mode to: MANUAL 
    DEBUG o.h.internal.SessionImpl - Disconnecting session 
    TRACE o.h.e.j.i.JdbcCoordinatorImpl - Releasing JDBC container resources [[email protected]] 
    TRACE o.h.e.j.i.JdbcCoordinatorImpl - Closing result set [[email protected]] 
    TRACE o.h.e.j.i.JdbcCoordinatorImpl - Closing prepared statement [select...] 
    DEBUG o.h.e.j.i.LogicalConnectionImpl - Releasing JDBC connection 
    DEBUG o.h.e.j.i.LogicalConnectionImpl - Released JDBC connection 
    DEBUG o.h.e.j.s.SqlExceptionHelper - could not advance using next() [n/a] org.postgresql.util.PSQLException: This ResultSet is closed. 
    

    有更多的東西,我可以做些什麼來阻止這種情況發生?

    +0

    是在OSIV過濾器內部實際映射的資源?其他一切都看起來不錯 – Affe

    +0

    我在攔截器配置中有',但沒有顯示,因爲沒有映射它通用。此外,這部分證明是可行的,因爲如果我不使用@Transactional,我得到了我的開放結果集。 –

    回答

    2

    默認情況下,Spring將自行管理Hibernate會話。在Javadoc HibernateTransactionManager中記錄的後果之一是,Spring將明確地呼叫session.disconnect(),這將使您的connection.release_mode=on_close設置失效。要改變這種行爲,Hibernate的管理會議,一定要在HibernateTransactionManager設置hibernateManagedSession屬性true

    <bean id="transactionManager" 
        class="org.springframework.orm.hibernate4.HibernateTransactionManager" 
        p:hibernateManagedSession="true" /> 
    

    這樣做,這樣勢必會擾亂其採用默認行爲的某些機制。其中之一是通過TransactionTemplate進行事務管理:不會自動創建Hibernate會話。這可以通過一個會議明確綁定到當前線程是固定的,在TransactionTemplate一個子類最佳拍攝:

    @Component 
    public class HibernateTransactionTemplate extends TransactionTemplate 
    { 
        @Autowired private SessionFactory sf; 
    
        @Autowired @Override public void setTransactionManager(PlatformTransactionManager txm) { 
        super.setTransactionManager(txm); 
        } 
    
        @Override public <T> T execute(TransactionCallback<T> action) throws TransactionException { 
        final Session ses = sf.openSession(); 
        TransactionSynchronizationManager.bindResource(sf, new SessionHolder(ses)); 
        try { return super.execute(action); } 
        finally { 
         ses.close(); 
         TransactionSynchronizationManager.unbindResource(sf); 
        } 
        } 
    }