有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

camel中的java JPA组件无法自动重新连接到数据库

当我在应用程序运行时重新启动数据库时,JPA组件无法自动重新连接

2017-02-09 17:45:08,400 ERROR o.h.e.j.spi.SqlExceptionHelper(131) - Connection closed. - [Camel (camel-1) thread #99 - jpa://com.toto.Toto  ]

但仍然我能够使用CXF路由中的spring数据执行SQL请求

我的数据源定义在上下文中。xml:

<!-- JDBC connection -->
    <Resource name="jdbc/oracle"
            auth="Container"
            type="javax.sql.DataSource"
            username="toto"
            password="toto"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            driverClassName="oracle.jdbc.driver.OracleDriver"
            url="jdbc:oracle:thin:@toto:1568:SID"
            maxTotal="100"
            maxIdle="10"
            testOnBorrow="true"
            validationQuery="select 1 from dual"/>

以下是我的JPA组件的外观:

    @Component
public class TotoPollerRoute extends RouteBuilder {

  private final String uri;

  private static final String POLLING_REQUEST = "select tt from Toto tt where tt.key = 1";

  public TotoPollerRoute() {
    super();
    final StringBuilder uriBuilder = new StringBuilder();
    uriBuilder.append("jpa://");
    uriBuilder.append(TotoPollerRoute.class.getName());
    uriBuilder.append("?");
    uriBuilder.append("consumeDelete=false");
    uriBuilder.append("&consumeLockEntity=true");
    uriBuilder.append("&consumer.SkipLockedEntity=true");
    uriBuilder.append("&maximumResults=10");
    uriBuilder.append("&consumer.query=");
    uriBuilder.append(POLLING_REQUEST);
    this.uri = uriBuilder.toString();
  }

  @Override
  public void configure() {
    // @formatter:off
    from(uri)
        .to("TotoMainRoute");
    // @formatter:on
  }
}

有什么想法吗


共 (2) 个答案

  1. # 1 楼答案

    尝试指定以下属性

    • validationInternal="30000"
    • testWhileIdle="true"
    • testOnReturn="false"

    除以下声明外,您还声明:

    • testOnBorrow="true"
    • validationQuery="select 1 from dual"
  2. # 2 楼答案

    经过一些深入的调试,我终于发现我的JPA组件没有使用Spring上下文中声明的EntityManagerFactory

    有两种解决方法:

    1. 修改每个JPA组件上的JPA uri并添加sharedEntityManager选项:

      private final String uri = "jpa://TotoPollerRoute?consumeDelete=false"
          + "&consumeLockEntity=true"
          + "&consumer.SkipLockedEntity=true"
          + "&maximumResults=10"
          + "&sharedEntityManager=true"
          + "&joinTransaction=false"
          + "&consumer.query=select tt from Toto tt where tt.key = 1";
      
    2. 在Spring中实例化JPA组件:

      @Bean
      public JpaComponent jpa() {
          final JpaComponent jpa = new JpaComponent();
          jpa.setSharedEntityManager(true);
          jpa.setJoinTransaction(false);
          return jpa;
      }