2016-04-02 207 views
1

我有一個在服務類中調用的EntityManager bean對象作爲自動裝配對象。連接丟失後自動重新連接JPA EntityManager

Spring配置類:

@EnableWebMvc 
@Configuration("myWebConfiguration") 
@ComponentScan(basePackages = {"org.my.app"}) 
@EnableScheduling 
public class MyWebConfiguration extends WebMvcConfigurerAdapter { 

.... 

    private static EntityManager entityManager; 

    @Bean 
    public EntityManager entityManager() { 
     if (entityManager == null) { 
      entityManager = managerFactoryBean().getObject().createEntityManager(); 
     } 
     return entityManager; 
    }  

....

private Properties hibernateProperties() { 
     Properties properties = new Properties(); 
     properties.setProperty("hibernate.hbm2ddl.auto", "update"); 
     properties.setProperty("hibernate.show_sql", "true"); 
     properties.setProperty("hibernate.format_sql", "true"); 
     properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL9Dialect"); 
     return properties; 
    } 

.... 

} 

樣品服務類:

@Service("sampleService") 
public class SampleService { 

    @Autowired 
    protected EntityManager entityManager; 

    public Object find(Class entityClass, Object id) { 
     return entityManager.find(entityClass, id); 
    } 

    .... 

} 

而且問題:

如果Web應用程序服務器之間的連接和DB服務器丟失,JPA和spring無法重新連接到數據庫服務器,並且調用entityManager方法會導致異常,如org.postgresql.util.PSQLException: This connection has been closed.org.hibernate.exception.JDBCConnectionException: could not inspect JDBC autocommit mode

是否可以自動檢測連接丟失並在連接丟失的情況下重新建立連接?

回答

1

這是可能的,這是由連接池(或支持連接池的數據源)庫實現的責任。

例如,如果您使用DBCP,則可以設置參數如validationQuery="SELECT 1"testOnBorrow="true",以允許檢測連接狀態並在需要時重新打開。

同樣,c3p0允許使用c3p0.testConnectionOnCheckout=true

其它連接池的庫將暴露類似的配置來配置這些參數。

如果您已經在使用連接池庫(或使用連接池的數據源),則可能需要檢查其文檔以獲取相關配置屬性。如果沒有,您可能需要考慮使用連接池庫或使用連接池的數據源並公開這些參數。

UPDATE: 對於C3P0可以添加以下屬性和測試:

properties.setProperty("hibernate.c3p0.preferredTestQuery","SELECT 1"); 
properties.setProperty("hibernate.c3p0.testConnectionOnCheckout","true"); 
+0

謝謝,我已經添加了休眠屬性部分答案。我使用c3p0,但我沒有配置它。我需要添加哪個配置? –

+0

@BabakBehzadi更新了c3p0屬性的答案。你可以試試這些。 –