如何编写一个适用于多个数据库和多个应用服务器的JPA主键生成器?
我目前正在进行一个Java/EJB/JPA项目,该项目有一个Swing客户机,该客户机部署到多个不同的应用程序服务器上,并支持多个不同的数据库。应用程序需要在以下服务器和数据库的任意组合上运行:如何编写一个适用于多个数据库和多个应用服务器的JPA主键生成器?,jpa,websphere,weblogic,Jpa,Websphere,Weblogic,我目前正在进行一个Java/EJB/JPA项目,该项目有一个Swing客户机,该客户机部署到多个不同的应用程序服务器上,并支持多个不同的数据库。应用程序需要在以下服务器和数据库的任意组合上运行: Servers: - Glassfish - JBoss - Websphere (WAS) Databases: - Oracle - MySql - Microsoft Sql Server 有没有一种使用JPA生成主键的方法可以在所有这些环境中使用。我尝试了许多不同的策略,并通过在JPA实体类
Servers:
- Glassfish
- JBoss
- Websphere (WAS)
Databases:
- Oracle
- MySql
- Microsoft Sql Server
有没有一种使用JPA生成主键的方法可以在所有这些环境中使用。我尝试了许多不同的策略,并通过在JPA实体类中使用此注释获得了最大的成功:
@Id
@Column( name = "ID" )
@TableGenerator(
name = "AppSeqStore",
table = "APP_SEQ_STORE",
pkColumnName = "APP_SEQ_NAME",
pkColumnValue = "LISTENER_PK",
valueColumnName = "APP_SEQ_VALUE",
initialValue = 1,
allocationSize = 1 )
@GeneratedValue( strategy = GenerationType.TABLE, generator = "AppSeqStore" )
数据库中的这个表:
CREATE TABLE APP_SEQ_STORE (
APP_SEQ_NAME VARCHAR(255) NOT NULL,
APP_SEQ_VALUE NUMBER(10) NOT NULL,
PRIMARY KEY(APP_SEQ_NAME)
)
INSERT INTO APP_SEQ_STORE VALUES ('LISTENER_PK', 0)
这些都可以在Oracle、MS Sql Server和使用JBoss作为应用服务器的MySql中使用。换句话说,它适用于我尝试使用JBoss的所有数据库
这在Webspe中不起作用此处为8.5.5.2,并给出以下例外情况Oracle是本例中的数据库:
[4/24/15 22:29:17:339 EDT] 00000079 BusinessExcep E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "addNewListenerTarget" on bean "BeanId(myappwas#myappserverejb.jar#ListenerDaoEJB, null)". Exception data: java.lang.UnsupportedOperationException
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.setRollbackOnly(WebSphereExtendedJtaPlatform.java:139)
at org.hibernate.ejb.AbstractEntityManagerImpl.markAsRollback(AbstractEntityManagerImpl.java:1169)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1319)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:881)
at com.ibm.ws.jpa.management.JPAExEmInvocation.persist(JPAExEmInvocation.java:317)
at com.ibm.ws.jpa.management.JPAEntityManager.persist(JPAEntityManager.java:143)
at com.apelon.server.ejb.ListenerDaoBean.addNewListenerTarget(ListenerDaoBean.java:243)
at com.apelon.server.dao.remote.EJSRemote0SLListenerDaoEJB_446f2106.addNewListenerTarget(EJSRemote0SLListenerDaoEJB_446f2106.java)
at com.apelon.server.dao.remote._EJSRemote0SLListenerDaoEJB_446f2106_Tie.addNewListenerTarget(_EJSRemote0SLListenerDaoEJB_446f2106_Tie.java:1)
at com.apelon.server.dao.remote._EJSRemote0SLListenerDaoEJB_446f2106_Tie._invoke(_EJSRemote0SLListenerDaoEJB_446f2106_Tie.java)
at com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:678)
at com.ibm.CORBA.iiop.ServerDelegate.dispatch(ServerDelegate.java:525)
at com.ibm.rmi.iiop.ORB.process(ORB.java:616)
at com.ibm.CORBA.iiop.ORB.process(ORB.java:1581)
at com.ibm.rmi.iiop.Connection.doRequestWork(Connection.java:3160)
at com.ibm.rmi.iiop.Connection.doWork(Connection.java:3030)
at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:64)
at com.ibm.ejs.oa.pool.PooledThread.run(ThreadPool.java:118)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1864)
你应该在你的stact跟踪中看到由下面某个地方引起的。我不相信这是由ID生成引起的,GenerationType.TABLE从JPA1开始就受到支持。此外,allocationSize=1是个坏主意,在复杂实体图(例如父实体和子实体列表)的一个持久化事件中,将生成多个id获取/更新语句,因为一次只能生成一个id,同时调用应用程序,这将导致瓶颈。AllocationSize-10是一款理智而安全的迷你电脑。感谢齐鲁的帮助!从下面的链接看,这是什么?Websphere实现的一个已知问题,特别是WebSphereExtendedjTapForm。我还没有彻底阅读这些条目,但它们似乎暗示这个类需要重写。我不确定重写后的代码会去哪里。如果这个类在我的项目中有正确的包,它会工作吗。我是否需要将其添加到Websphere代码中?这是Websphere已经或将要解决的问题吗?有更好的解决方案吗?链接:这是现有的类似解决方案。这是他们引用的解决方案:。这是指向上面第二个链接的更改请求的死链接:。很抱歉,我无法帮助您。我使用独立的hibernate或eclipselink,id生成策略就在那里起作用。