1

I'm currently on a project (Java/EJB/JPA with a Swing client) that is deployed to several different app servers and supports several different databases. The application is required to run on any combination of the following servers and databases:

Servers:
- Glassfish
- JBoss
- Websphere (WAS)

Databases:
- Oracle
- MySql
- Microsoft Sql Server

Is there one way to generate a primary key using JPA that will work in all of these environments. I have tried a number of different strategies and have gotten the farthest by using this annotation in the JPA Entity class:

@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" )

And this table in the database:

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)

This all works in Oracle, and MS Sql Server, and MySql using JBoss as the App Server. In other words it works with all of the databases I've tried using JBoss.

This does not work in Webspehere (WAS 8.5.5.2) and gives the following exception (Oracle was the database in this case):

[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)
Cœur
  • 37,241
  • 25
  • 195
  • 267
John
  • 3,458
  • 4
  • 33
  • 54
  • 1
    You should see caused by somewhere below in your stact trace. I don't believe it is cause by ID generation, GenerationType.TABLE was supported since JPA 1. Also allocationSize=1 is a bad idea, in one persist event for complex entity graph (for example parent entity and list of childs) multiple id fetching/updating statements will be generated (as only one id can be generated at a time), with concurrent calls to the application it will cause a bottle neck. AllocationSize-10 is a sane and safe mininum. – Zielu Apr 26 '15 at 08:59
  • Thanks for the help Zielu! From the links below it looks like this is (was?) a known issue of the Websphere implementation, specifically WebSphereExtendedJtaPlatform. I haven’t read through these items thoroughly yet but it looks like they are suggesting that this class needs to be rewritten. I’m not sure where the rewritten code would go. Would it work if this class was in my project (in the correct package). Do I need to add this to the Websphere code? Is this something that has been or will be address by Websphere? Is there a better solution? – John Apr 26 '15 at 17:33
  • LINKS: This is an existing similar http://stackoverflow.com/questions/13388069/unexpected-unsupportedoperationexception-on-hibernate-validation-failure. This is a solution they reference: https://forum.hibernate.org/viewtopic.php?f=1&t=992310 . This is a dead link to a change request from the second link above: https://hibernate.jira.com/browse/HHH-2703 . – John Apr 26 '15 at 18:01
  • 1
    I am sorry I cannot help you with that. I use stand alone hibernate or eclipselink and that id generation strategy just works there. – Zielu Apr 26 '15 at 20:31

0 Answers0