如何在 JPA 和 Spring 的同一 persistence.xml 中使用两个不同的实体?
How to use two different entities in the same persistence.xml with JPA and Spring?
我正在尝试构建一个 Spring-MVC
portlet,它通过 JPA 与 MySQL
数据库的两个不同 table 进行交互。我读过大约 7 个不同的 posts 来处理这个主题和我得到的错误,但没有任何帮助我。如果我只使用这些 table 中的一个,该程序可以完美运行,但如果我将另一个 table 添加为 entity
,我会收到错误消息。两个实体 classes 都是由 IBM 的 Rational Application Developer
的 JPA Tools
自动生成的。
我的来源:
因为 *Manager.java
几乎相同 post 代码只有一次:
//imports
@SuppressWarnings("unchecked")
@JPAManager(targetEntity = entities.BookTbl.class)
public class BookTblManager {
private EntityManagerFactory emf;
public BookTblManager() {
emf = EMFProvider.getEMF();
}
public BookTblManager(EntityManagerFactory emf) {
this.emf = emf;
}
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
private EntityManager getEntityManager() {
if (emf == null) {
throw new RuntimeException(
"The EntityManagerFactory is null. This must be passed in to the constructor or set using the setEntityManagerFactory() method.");
}
return emf.createEntityManager();
}
//Create, delete, update methods
我的EMFProvider.java
(EntityManagerFactory 提供商):
//Imports
public class EMFProvider {
private static EntityManagerFactory emf;
private static final String project = "SpringJPASample";
public EMFProvider() {
}
public static synchronized EntityManagerFactory getEMF() {
if (emf == null) {
emf = Persistence.createEntityManagerFactory(project);
}
return emf;
}
}
我的persistence.xml
:
...
<persistence-unit name="SpringJPA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>entities.User</class>
<class>entities.BookTbl</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/portlet" />
<property name="javax.persistence.jdbc.user" value="admin" />
<property name="javax.persistence.jdbc.password" value="password" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
...
最后我的错误:
Caused by: java.lang.NoSuchMethodError: javax/persistence/Table.indexes()[Ljavax/persistence/Index;
at org.hibernate.cfg.annotations.EntityBinder.processComplementaryTableDefinitions(EntityBinder.java:1108)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:774)
at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:245)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.processEntityHierarchies(MetadataBuildingProcess.java:222)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:265)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:848)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:875)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:135)
at com.ibm.ws.jpa.management.JPAPUnitInfo.createEMFactory(JPAPUnitInfo.java:1584)
at com.ibm.ws.jpa.management.JPAPUnitInfo.createEntityManagerFactory(JPAPUnitInfo.java:1406)
at com.ibm.ws.jpa.management.JPAPxmlInfo.extractPersistenceUnits(JPAPxmlInfo.java:246)
at com.ibm.ws.jpa.management.JPAScopeInfo.processPersistenceUnit(JPAScopeInfo.java:119)
at com.ibm.ws.jpa.management.JPAApplInfo.processModulePUs(JPAApplInfo.java:167)
at com.ibm.ws.jpa.management.AbstractJPAComponent.startingModule(AbstractJPAComponent.java:451)
at com.ibm.ws.jpa.management.JPAComponentImpl.startingDeployedModule(JPAComponentImpl.java:729)
at com.ibm.ws.jpa.management.JPAComponentImpl.adjust(JPAComponentImpl.java:549)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.adjust(ApplicationMgrImpl.java:1069)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectAdjust(DeployedApplicationImpl.java:1394)
at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:627)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:968)
... 66 more
I'm using the Websphere Portal Server 8.5, Spring 4.3.2, Hibernate 5.1 and JPA 2.1.
我尝试了其他 post 中提到的关于此错误的任何解决方案,但没有任何效果。而且我 不想 想使用两个不同的数据库,我不想在一个 class.
中同时使用两个 table
尝试使用 WebSphere Application Server 中的类加载器查看器来解决类加载问题https://www.ibm.com/support/knowledgecenter/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/utrb_classload_viewer_service.html
这可能是因为 WebSphere v8.5 不支持 JPA 2.1。它仅支持 JPA 2.0 API。因此,JPA 2.0 API 由 WebSphere 加载,而这个版本不足以(与)此版本的 Hibernate 一起使用,因为它基于 JPA 2.1。
如果您想将 JPA 2.1 与 WebSphere v8.5 一起使用,那么您将只能使用应用程序管理的持久性。有关此配置和用法的更多详细信息,请参见此处:
Websphere 8.5 with JPA 2.1
我正在尝试构建一个 Spring-MVC
portlet,它通过 JPA 与 MySQL
数据库的两个不同 table 进行交互。我读过大约 7 个不同的 posts 来处理这个主题和我得到的错误,但没有任何帮助我。如果我只使用这些 table 中的一个,该程序可以完美运行,但如果我将另一个 table 添加为 entity
,我会收到错误消息。两个实体 classes 都是由 IBM 的 Rational Application Developer
的 JPA Tools
自动生成的。
我的来源:
因为 *Manager.java
几乎相同 post 代码只有一次:
//imports
@SuppressWarnings("unchecked")
@JPAManager(targetEntity = entities.BookTbl.class)
public class BookTblManager {
private EntityManagerFactory emf;
public BookTblManager() {
emf = EMFProvider.getEMF();
}
public BookTblManager(EntityManagerFactory emf) {
this.emf = emf;
}
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
private EntityManager getEntityManager() {
if (emf == null) {
throw new RuntimeException(
"The EntityManagerFactory is null. This must be passed in to the constructor or set using the setEntityManagerFactory() method.");
}
return emf.createEntityManager();
}
//Create, delete, update methods
我的EMFProvider.java
(EntityManagerFactory 提供商):
//Imports
public class EMFProvider {
private static EntityManagerFactory emf;
private static final String project = "SpringJPASample";
public EMFProvider() {
}
public static synchronized EntityManagerFactory getEMF() {
if (emf == null) {
emf = Persistence.createEntityManagerFactory(project);
}
return emf;
}
}
我的persistence.xml
:
...
<persistence-unit name="SpringJPA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>entities.User</class>
<class>entities.BookTbl</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/portlet" />
<property name="javax.persistence.jdbc.user" value="admin" />
<property name="javax.persistence.jdbc.password" value="password" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
...
最后我的错误:
Caused by: java.lang.NoSuchMethodError: javax/persistence/Table.indexes()[Ljavax/persistence/Index;
at org.hibernate.cfg.annotations.EntityBinder.processComplementaryTableDefinitions(EntityBinder.java:1108)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:774)
at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:245)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.processEntityHierarchies(MetadataBuildingProcess.java:222)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:265)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:848)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:875)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:135)
at com.ibm.ws.jpa.management.JPAPUnitInfo.createEMFactory(JPAPUnitInfo.java:1584)
at com.ibm.ws.jpa.management.JPAPUnitInfo.createEntityManagerFactory(JPAPUnitInfo.java:1406)
at com.ibm.ws.jpa.management.JPAPxmlInfo.extractPersistenceUnits(JPAPxmlInfo.java:246)
at com.ibm.ws.jpa.management.JPAScopeInfo.processPersistenceUnit(JPAScopeInfo.java:119)
at com.ibm.ws.jpa.management.JPAApplInfo.processModulePUs(JPAApplInfo.java:167)
at com.ibm.ws.jpa.management.AbstractJPAComponent.startingModule(AbstractJPAComponent.java:451)
at com.ibm.ws.jpa.management.JPAComponentImpl.startingDeployedModule(JPAComponentImpl.java:729)
at com.ibm.ws.jpa.management.JPAComponentImpl.adjust(JPAComponentImpl.java:549)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.adjust(ApplicationMgrImpl.java:1069)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectAdjust(DeployedApplicationImpl.java:1394)
at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:627)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:968)
... 66 more
I'm using the Websphere Portal Server 8.5, Spring 4.3.2, Hibernate 5.1 and JPA 2.1.
我尝试了其他 post 中提到的关于此错误的任何解决方案,但没有任何效果。而且我 不想 想使用两个不同的数据库,我不想在一个 class.
中同时使用两个 table尝试使用 WebSphere Application Server 中的类加载器查看器来解决类加载问题https://www.ibm.com/support/knowledgecenter/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/utrb_classload_viewer_service.html
这可能是因为 WebSphere v8.5 不支持 JPA 2.1。它仅支持 JPA 2.0 API。因此,JPA 2.0 API 由 WebSphere 加载,而这个版本不足以(与)此版本的 Hibernate 一起使用,因为它基于 JPA 2.1。
如果您想将 JPA 2.1 与 WebSphere v8.5 一起使用,那么您将只能使用应用程序管理的持久性。有关此配置和用法的更多详细信息,请参见此处: Websphere 8.5 with JPA 2.1