连接丢失后自动重新连接JPA EntityManager

时间:2016-04-02 07:57:03

标签: java spring hibernate postgresql jpa

我有一个在服务类中调用的EntityManager bean对象作为自动对象。

Spring Config类:

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

    ....

}

问题是:

如果WebApp服务器和数据库服务器之间的连接丢失,JPA和spring无法重新连接到数据库服务器,调用entityManager方法会导致org.postgresql.util.PSQLException: This connection has been closed.org.hibernate.exception.JDBCConnectionException: could not inspect JDBC autocommit mode等异常。

是否可以自动检测连接丢失并在连接丢失时重新建立连接?

1 个答案:

答案 0 :(得分:3)

这是可能的,这是连接池(或支持连接池的数据源)库所实现的责任。

例如,如果您使用DBCP,则可以设置validationQuery="SELECT 1"testOnBorrow="true"等参数,以便检测连接状态并在需要时重新打开。

同样,c3p0允许使用c3p0.testConnectionOnCheckout=true等配置此类参数。

其他连接池库将公开类似的配置。

如果您已在使用连接池库(或使用连接池的数据源),则可能需要检查其文档以获取要设置的相关配置属性。如果没有,您可能需要考虑使用连接池库或使用连接池的数据源并公开这些参数。

<强>更新 对于c3p0,您可以添加以下属性并进行测试:

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