【问题标题】:Connection is closed when using Hibernate Search with Spring application将 Hibernate Search 与 Spring 应用程序一起使用时连接已关闭
【发布时间】:2020-04-10 23:20:13
【问题描述】:

自从我在我的应用程序中添加了 Hibernate Search 后,我似乎在一段时间后失去了与 Hikari 池的连接(似乎超过 8 小时)

我已经为这个错误苦苦挣扎了整整一周,但我真的不知道为什么会这样:

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not prepare statement

Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement

Caused by: java.sql.SQLException: Connection is closed

我试过了: 设置一些 hikari 的属性,例如:

 spring.datasource.type=com.zaxxer.hikari.HikariDataSource
 spring.datasource.hikari.minimumIdle=20
 spring.datasource.hikari.maximumPoolSize=100
 spring.datasource.hikari.idleTimeout=300000
 spring.datasource.hikari.poolName=SpringBootJPAHikariCP
 spring.datasource.hikari.maxLifetime=200000
 spring.datasource.hikari.connectionTimeout=20000
 spring.datasource.hikari.registerMbeans=true

将我的 bean 配置为使用如下所示的 testQuery:

    public DataSource siteDataSource() {

    HikariConfig config = new HikariConfig();
    HikariDataSource dataSource;

    config.setJdbcUrl(env.getProperty("spring.mysql.datasource.url"));
    config.setUsername(env.getProperty("spring.mysql.datasource.username"));
    config.setPassword(env.getProperty("spring.mysql.datasource.password"));
    config.setDriverClassName(env.getProperty("spring.mysql.datasource.driver-class-name"));
    config.setMaximumPoolSize(15);
    config.setConnectionTestQuery("SELECT 1");

    // performance senstive settings
    config.setMinimumIdle(0);
    config.setConnectionTimeout(30000);
    config.setIdleTimeout(35000);
    config.setMaxLifetime(45000);
    dataSource = new HikariDataSource(config);

    return dataSource;
}

(这个配置的东西也被删除了,错误还是一样)

并使用:

autoReconnect=true

我也收到了下面的错误,这似乎在当前的实现中消失了(但老实说,我不知道为什么 - 是的,我在这里很迷茫):

Caused by: com.mysql.cj.exceptions.CJCommunicationsException: The last packet successfully received from the server was 50,090,585 milliseconds ago.  The last packet sent successfully to the server was 50,090,585 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

我什至不知道如何重现此错误。我必须等待一整天才能为每个新测试再次测试它。

似乎是Tomcat + Hibernate + Hikari,但老实说,我没有任何进一步的想法。

你们知道如何解决这个问题,甚至如何在短时间内重现这个错误吗?

谢谢。

【问题讨论】:

  • 我已经读过了。我已经尝试了他们建议的一切。我唯一没有尝试的事情(因为看起来非常糟糕)是让一个 cron 工作每小时发出一个虚假请求以保持连接活跃。
  • 我找不到解决方案...
  • 我假设您有一些代码不会将数据库连接返回到池。例如您在某处使用连接对象。 “从服务器成功接收到的最后一个数据包是 50,090,585 毫秒”可以与您锁定将心跳请求发送到数据库的线程相关联。我建议进行线程转储以检查线程状态。
  • 我通过每分钟发出一个随机请求以保持连接处于活动状态来管理它。到目前为止,我没有发现其他更好的东西。

标签: java hibernate tomcat connection-pooling connection-close


【解决方案1】:

帮助我们解决相同问题的步骤:

  • 升级您的 SpringBoot 版本。
  • 升级您的数据库连接器库版本。
  • 删除其他数据库连接池库,通常应该使用 SpringBoot 中的默认 Hikari。

【讨论】:

  • 你有更新到哪个版本的 Spring Boot、Hibernate Search 和 Hibernate ORM 的更详细信息吗?
  • 获取最新的 Springboot(当前为 2.5.0)并删除其他依赖项的版本。 Springboot 有自己的兼容库版本列表。如果没有 - 尝试按库和 springboot 发布日期查找匹配的版本。
【解决方案2】:

我通过重新创建 entityManager 对象解决了这个错误

this.entityManager = entityManagerFactory.createEntityManager();

所以您需要做的就是:捕获异常并重新创建 entityManager 对象,然后再次搜索

可选读取(手动索引推荐):当我通过 Jpa 将任何对象保存(创建/更新)到数据库时

repository.save(obj)

发现对象在 hibernate-search 中没有索引(Lucien/Elastic Search/..),所以我必须在将对象保存到数据库后手动索引它(但是从数据库中删除索引对象时,我不必手动删除它)。

repository.save(objFromDB);
manualIndexToHibernateSearch(objFromDB);
...
public void manualIndexToHibernateSearch(MyObject objFromDB) {
    FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
    fullTextEntityManager.getTransaction().begin();
    //find object by id in hibernate-search 
    MyObject objFromHibernateSearch = fullTextEntityManager.find(MyObject.class, objFromDB.getId());
    //you have to replace 'text' field with your fields that have @Field annotation
    objFromHibernateSearch.setText(objFromDB.getText());
    //index
    fullTextEntityManager.index(objFromHibernateSearch);
    //commit
    fullTextEntityManager.getTransaction().commit();
}

【讨论】:

    猜你喜欢
    • 2014-06-22
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    相关资源
    最近更新 更多