hibernate - 从 JPA2.0 迁移到 JPA 2.1 时出现 "Unsupported use of GenericConnection"异常

标签 hibernate jpa websphere eclipselink openjpa

我们正在从 WAS 8.5(为 JPA 2.0 使用 openJPAHibernate 4.2.x [最新的 JPA 2.0 版本])迁移到 WAS 9.0(将 eclipseLink 用于 JPA 2.1 和 Hibernate 5.2.18 [最新的 JPA 2.1 版本]),除了一件事外,迁移是成功的。

为了能够在服务器上多次部署相同的应用程序并针对不同的数据库运行,我们定义了一个变量 DataSourcepersistence.xml 中引用:

  <persistence-unit name="App_DB" transaction-type="JTA">

    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>java:comp/env/jdbc/app/dataSourceRef</jta-data-source>

    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect" />
      <property name="connection.autocommit" value="false" />           

      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
      <property name="jta.UserTransaction" value="java:comp/UserTransaction" />

      <property name="hibernate.hbm2ddl.auto" value="validate" />
      <property name="javax.persistence.validation.mode" value="none" />
    </properties>

  </persistence-unit>

如您所见<jta-data-source>是一个引用。引用绑定(bind)在 ibm-ejb-jar-bnd.xml

<session name="StartUpService">
  <resource-ref name="jdbc/app/dataSourceRef" binding-name="jdbc/app/appDB"/>
</session>

并在类中使用如下:

@Singleton
@Startup
@LocalBean
public class StartUpService {

  @Resource(name = "jdbc/app/dataSourceRef", type = DataSource.class)
  DataSource dataSource;  

}

这对 WAS 8.5/openJPA 来说一切正常。但是,当使用 WAS 9.0/eclipseLink 时,这将不再有效,并在您尝试启动应用程序时产生以下异常:

[WebContainer : 4] ERROR org.hibernate.hql.spi.id.IdTableHelper - Unable to use JDBC Connection to create Statement java.sql.SQLException: Unsupported use of GenericConnection. A GenericConnection is provided during application start when creating an EntityManagerFactory for a persistence unit which has configured one of its datasource to be in the component naming context; java:comp/env. During application start, the component naming context will not exist, and the correct datasource cannot be determined. When the persistence unit is used, the proper datasource and connection will be obtained and used. at com.ibm.ws.jpa.management.GenericConnection.unsupportedUseSQLException(GenericConnection.java:636) ~[com.ibm.ws.runtime.jar:?] at com.ibm.ws.jpa.management.GenericConnection.createStatement(GenericConnection.java:144) ~[com.ibm.ws.runtime.jar:?] at org.hibernate.hql.spi.id.IdTableHelper.executeIdTableCreationStatements(IdTableHelper.java:77) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] at org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy.finishPreparation(GlobalTemporaryTableBulkIdStrategy.java:125) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] at org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy.finishPreparation(GlobalTemporaryTableBulkIdStrategy.java:42) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] at org.hibernate.hql.spi.id.AbstractMultiTableBulkIdStrategyImpl.prepare(AbstractMultiTableBulkIdStrategyImpl.java:88) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:305) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:945) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:151) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] at com.ibm.ws.jpa.management.JPAPUnitInfo.createEMFactory(JPAPUnitInfo.java:1161) [com.ibm.ws.runtime.jar:?]

 [...]

at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1909) [com.ibm.ws.runtime.jar:?]

[WebContainer : 4] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Unsupported use of GenericConnection. A GenericConnection is provided during application start when creating an EntityManagerFactory for a persistence unit which has configured one of its datasource to be in the component naming context; java:comp/env. During application start, the component naming context will not exist, and the correct datasource cannot be determined. When the persistence unit is used, the proper datasource and connection will be obtained and used.

000000a1 JPAPUnitInfo E CWWJP0015E: An error occurred in the org.hibernate.jpa.HibernatePersistenceProvider persistence provider when it attempted to create the container entity manager factory for the App_DB persistence unit. The following error occurred: [PersistenceUnit: App_DB] Unable to build Hibernate SessionFactory

所以看来 Hibernate 无法确定 DataSource .当我设置 <jta-data-source> 的完整 JDNI 名称时而不是这样的引用

<jta-data-source>jdbc/app/appDB</jta-data-source> 

应用程序完美启动,Hibernate 可以在启动时执行模式验证和所有操作。

当我在网上搜索这个问题时,我找到了 suggestion你应该添加 javax.persistence.jtaDataSource"persistence.xml<jta-data-source> 具有相同的值像这样:

<property name="javax.persistence.jtaDataSource" value="java:comp/env/jdbc/app/dataSourceRef" />

但这并没有改变我的情况。同样的错误,没有成功启动。

所以我很想知道以下问题的答案:

  1. 主要问题:如何定义我的 persistence.xml使用DataSource再次引用?如果启动验证是针对应用程序的所有实例的同一个数据库进行的,即使正在运行的应用程序在启动后会使用另一个数据源,因为我显然想验证 DataSource该实例真正使用。 注意:更改 JPA 实现不会由我们的管理员完成 - 他们只会坚持 IBM 支持的原始配置。

  2. 小问题:为什么 Hibernate (4.2.x) 结合 openJPA 可以使用 WAS 8.5 中的引用,但是 Hibernate (5.2.18) 与 eclipseLink 的结合不能在 WAS 9.0 中做到这一点?

最佳答案

对我有帮助的解决方案:

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/myTest</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.target-database" value="Oracle"/>
<property name="eclipselink.target-server" value="WebSphere"/>
<property name="eclipselink.logging.level" value="FINEST"/>
<property name="javax.persistence.jtaDataSource" value="jdbc/myTest" />
</properties>
</persistence-unit>

所以基本上错误是通过属性声明确认 jtaDataSource。

最后但同样重要的是,删除:

java:comp/env/jdbc/myTest

并放置简单的 JNDI 引用:

jdbc/myTest

关于hibernate - 从 JPA2.0 迁移到 JPA 2.1 时出现 "Unsupported use of GenericConnection"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59917179/

相关文章:

java - 在 Struts 2 中使用 ModelDriven 的多个不同的 POJO

java - JPA 中的地理空间支持

java - Criteria Builder JOIN 未引用的表

java - 如何使用@ConstructorResult注解

java - 如何从Websphere启动工作任务进一步传递异常?

java - 如何处理由于 WebSphere 中的多个 AJAX 请求而导致的高线程使用率

jakarta-ee - 如何为WebSphere 8.5编写EJB 3.1客户端?

java - 使用什么级联类型来仅保存多对多映射的子级列表?

java - JdbcTemplate 抛出 java.sql.SQLException :

java - doc文件未在jsp中显示