【发布时间】:2020-05-12 00:07:01
【问题描述】:
我们正在从 WAS 8.5(JPA 2.0 使用 openJPA,Hibernate 4.2.x [last JPA 2.0 version])迁移到 WAS 9.0 em>(它使用 eclipseLink 用于 JPA 2.1 和 Hibernate 5.2.18 [最后一个 JPA 2.1 版本]),除了迁移成功的一件事。
为了能够在服务器上多次部署相同的应用程序并针对不同的数据库运行,我们在persistence.xml 中定义了一个变量DataSource 引用:
<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> 是一个参考。引用绑定在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] 错误 org.hibernate.hql.spi.id.IdTableHelper - 无法使用 JDBC 连接创建语句 java.sql.SQLException:不支持使用 GenericConnection。 GenericConnection 在应用程序启动期间为已将其数据源之一配置为在组件命名上下文中的持久性单元创建 EntityManagerFactory 时提供; java:comp/环境。在应用程序启动期间,组件命名上下文将不存在,并且无法确定正确的数据源。当使用持久化单元时,将获得并使用正确的数据源和连接。 在 com.ibm.ws.jpa.management.GenericConnection.unsupportedUseSQLException(GenericConnection.java:636) ~[com.ibm.ws.runtime.jar:?] 在 com.ibm.ws.jpa.management.GenericConnection.createStatement(GenericConnection.java:144) ~[com.ibm.ws.runtime.jar:?] 在 org.hibernate.hql.spi.id.IdTableHelper.executeIdTableCreationStatements(IdTableHelper.java:77) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] 在 org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy.finishPreparation(GlobalTemporaryTableBulkIdStrategy.java:125) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] 在 org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy.finishPreparation(GlobalTemporaryTableBulkIdStrategy.java:42) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] 在 org.hibernate.hql.spi.id.AbstractMultiTableBulkIdStrategyImpl.prepare(AbstractMultiTableBulkIdStrategyImpl.java:88) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] 在 org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:305) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] 在 org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] 在 org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:945) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] 在 org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:151) [org.hibernate-hibernate-core-5.2.18.Final.jar:5.2.18.Final] 在 com.ibm.ws.jpa.management.JPAPUnitInfo.createEMFactory(JPAPUnitInfo.java:1161) [com.ibm.ws.runtime.jar:?]
[...]在 com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1909) [com.ibm.ws.runtime.jar:?]
[WebContainer : 4] 错误 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - 不支持使用 GenericConnection。 GenericConnection 在应用程序启动期间为已将其数据源之一配置为在组件命名上下文中的持久性单元创建 EntityManagerFactory 时提供; java:comp/环境。在应用程序启动期间,组件命名上下文将不存在,并且无法确定正确的数据源。当使用持久化单元时,将获得并使用正确的数据源和连接。
000000a1 JPAPUnitInfo E CWWJP0015E: org.hibernate.jpa.HibernatePersistenceProvider 持久性提供程序尝试为 App_DB 持久性单元创建容器实体管理器工厂时发生错误。出现以下错误:[PersistenceUnit: App_DB] 无法构建 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" />
但这并没有改变我的情况。同样的错误,没有成功启动。
所以我很想得到以下问题的答案:
主要问题:如何定义我的
persistence.xml以再次使用DataSource引用?如果启动验证是针对应用程序的所有实例的同一个数据库进行的,即使正在运行的应用程序在启动后会使用另一个数据源,也没有帮助,因为我显然想验证实例真正使用的DataSource. 注意:我们的管理员不会更改 JPA 实现 - 他们只会坚持 IBM 支持的原始配置原因。小问题:为什么Hibernate(4.2.x)结合openJPA可以使用WAS 8.5中的引用,但是 Hibernate (5.2.18) 结合 eclipseLink 不能在 WAS 9.0 中做到这一点?
【问题讨论】:
-
如果您不使用 EclipseLink 作为持久性提供程序,它是如何影响这个问题和问题的?
-
您的意思是指定“javax.persistence.jtaDataSource”持久性属性,如下所述:j2code.blogspot.com/2012/10/websphere-jpa-and-local-jndi.html?这是针对 EclipseLink 的,在指定
标记时不应该需要,因此他们在 IBM 服务器上的设置存在问题,这可以解决。我猜想多个提供程序 jar 的类加载器问题,它们使用全局数据源名称,而不是像你一样的映射引用。查看您如何在类路径中使用 Hibernate 以及如何定义数据源。 -
@ChrisYeah 那是我发现的关于此的博客之一,正如所写,添加此属性没有任何改变。 EclipseLink IS 由 IBM 在 WAS 9 中配置。在 WAS 8.5 中它是 openJPA
-
Eclipselink 只是一个包含在 WAS 中的 jar,如果您不指定提供者标记,则作为默认提供者。正如错误所示,它根本不涉及错误或问题。该错误表明 Hibernate 正在尝试使用临时数据源来发出 DDL 语句,直到 WAS 进入部署的后期阶段才被允许。您可以尝试使用 EclipseLink 来查看它是否可以作为问题所在的反点,但是您必须查看所使用的版本中的休眠差异,以查看这是否存在差异或 WAS 行为本身。
-
你把eclipse链接和hibernate搞混了。为了使用 hibernate over eclipselink 作为 websphere 默认提供程序,您需要将您的应用程序设置为 PARENT_LAST 以避免加载 WAS 类加载器。更改您的 deployment.xml 文件。
标签: hibernate jpa websphere eclipselink openjpa