DayTrader
  1. DayTrader
  2. DAYTRADER-63

OrderDataBean @OneToOne mapping to HoldingDataBean causes sell operation failed

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.1.3, 2.2
    • Fix Version/s: 2.1.3, 2.2
    • Component/s: EJB Tier
    • Labels:
      None
    • Environment:

      JDK: 1.5 or later
      Geronimo: 2.2-snapshot
      DB: DB2

      Description

      If enable OpenJPA to create foreign key constraints on db2 database, in EJB3 runtime mode, the sell operation will fail by throwing exception like this:

      2009-01-09 11:50:10,642 WARN [Transaction] Unexpected exception from beforeCompletion; transaction will roll back
      <openjpa-1.0.3-r420667:677674 fatal general error> org.apache.openjpa.persistence.PersistenceException: The transaction has been rolled back. See the nested exceptions for details on the errors that occurred.
      at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2108)
      at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1955)
      at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1853)
      at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1771)
      at org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:514)
      at org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:499)
      at org.apache.geronimo.transaction.manager.TransactionImpl.beforePrepare(TransactionImpl.java:400)
      at org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:257)
      at org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:245)
      at org.apache.openejb.core.transaction.TransactionPolicy.commitTransaction(TransactionPolicy.java:138)
      at org.apache.openejb.core.transaction.TxRequired.afterInvoke(TxRequired.java:76)
      at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:212)
      at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:188)
      at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:165)
      at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:217)
      at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:77)
      at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:245)
      at org.apache.openejb.util.proxy.Jdk13InvocationHandler.invoke(Jdk13InvocationHandler.java:49)
      at $Proxy68.sell(Unknown Source)
      at org.apache.geronimo.samples.daytrader.TradeAction.sell(TradeAction.java:237)
      at org.apache.geronimo.samples.daytrader.web.TradeServletAction.doSell(TradeServletAction.java:690)
      at org.apache.geronimo.samples.daytrader.web.TradeAppServlet.performTask(TradeAppServlet.java:162)
      at org.apache.geronimo.samples.daytrader.web.TradeAppServlet.doGet(TradeAppServlet.java:77)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:693)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.geronimo.samples.daytrader.web.OrdersAlertFilter.doFilter(OrdersAlertFilter.java:91)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.apache.geronimo.tomcat.valve.DefaultSubjectValve.invoke(DefaultSubjectValve.java:56)
      at org.apache.geronimo.tomcat.GeronimoStandardContext$SystemMethodValve.invoke(GeronimoStandardContext.java:406)
      at org.apache.geronimo.tomcat.valve.GeronimoBeforeAfterValve.invoke(GeronimoBeforeAfterValve.java:47)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:568)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Thread.java:735)
      Caused by:
      <openjpa-1.0.3-r420667:677674 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: DB2 SQL error: SQLCODE: -532, SQLSTATE: 23504, SQLERRMC: DB2ADMIN.ORDEREJB.SQL090109114758260

      {prepstmnt 1005206506 DELETE FROM holdingejb WHERE HOLDINGID = ? [params=(int) 1]} [code=-532, state=23504]SQLCA OUTPUT[Errp=SQLRI079, Errd=-2145779603, 0, 0, 0, -90, 0]
      FailedObject: org.apache.geronimo.samples.daytrader.HoldingDataBean-1
      at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:3951)
      at org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:476)
      at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:97)
      at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:67)
      at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:108)
      at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:73)
      at org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flushPrimaryRow(OperationOrderUpdateManager.java:162)
      at org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flush(OperationOrderUpdateManager.java:89)
      at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:89)
      at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:72)
      at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:514)
      at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
      ... 43 more
      Caused by:
      org.apache.openjpa.lib.jdbc.ReportingSQLException: DB2 SQL error: SQLCODE: -532, SQLSTATE: 23504, SQLERRMC: DB2ADMIN.ORDEREJB.SQL090109114758260 {prepstmnt 1005206506 DELETE FROM holdingejb WHERE HOLDINGID = ? [params=(int) 1]}

      [code=-532, state=23504]
      at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:192)
      at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$800(LoggingConnectionDecorator.java:57)
      at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:858)
      at org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:269)
      at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeUpdate(JDBCStoreManager.java:1363)
      at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:97)
      ... 50 more

        Activity

        Hide
        Donald Woods added a comment -

        Applied to trunk as Rev752864

        Show
        Donald Woods added a comment - Applied to trunk as Rev752864
        Hide
        Donald Woods added a comment -

        Patch applied to Daytrader 2.1.3 as Rev752851

        Show
        Donald Woods added a comment - Patch applied to Daytrader 2.1.3 as Rev752851
        Hide
        Forrest Xia added a comment -

        Hi Donald,

        All three patches are for daytrader trunk.
        Daytrader-63
        Daytrader-64
        Daytrader-65

        Thanks!

        Forrest

        Show
        Forrest Xia added a comment - Hi Donald, All three patches are for daytrader trunk. Daytrader-63 Daytrader-64 Daytrader-65 Thanks! Forrest
        Hide
        Forrest Xia added a comment -

        Hi David,

        The problem this patch tends to fix is not about OpenJPA database support issue or any database vendor bug. I think it's a daytrader bug.

        Here is my finding:
        By default, OpenJPA won't generate FK constraints, even you use a config property like this:
        <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

        So using Geronimo to run daytrader, the EJB3 annotation defined relationships(FKs) will never be created by OpenJPA on tables, unless you add another OpenJPA config property like this:
        <property name="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=restrict,JoinForeignKeyDeleteAction=restrict"/>

        But when I am doing a migration to JBoss 5, which uses Hibernate as JPA provider, I used a hibernate config property like this:
        <property name="hibernate.hbm2ddl.auto" value="update"/>
        Hibernate will generate DDL according to EJB3 annotations in daytrader entity beans, and create FKs constraints on tables.

        Then when doing a sell operation in Full EJB3 runtime mode, an exception will be thrown:
        2009-01-07 23:58:25,323 DEBUG [org.hibernate.util.JDBCExceptionReporter] (http-127.0.0.1-8080-1) could not delete: org.apache.geronimo.samples.daytrader.HoldingDataBean#1001 [delete from holdingejb where HOLDINGID=?]
        com.ibm.db2.jcc.b.lm: DB2 SQL Error: SQLCODE=-532, SQLSTATE=23504, SQLERRMC=DB2ADMIN.ORDEREJB.FK4992164F3AE187D6, DRIVER=3.50.152
        at com.ibm.db2.jcc.b.wc.a(wc.java:575)
        at com.ibm.db2.jcc.b.wc.a(wc.java:57)
        at com.ibm.db2.jcc.b.wc.a(wc.java:126)
        ...

        The FK4992164F3AE187D6 is from annotated relationship on OrderDataBean property
        @OneToOne(fetch=FetchType.LAZY)
        @JoinColumn(name = "HOLDING_HOLDINGID")
        private HoldingDataBean holding;

        It stop deleting any holdings from holdingejb table, thus cause sell operation failed.

        For DIRECT runtime mode, the FK constraints will never be created, so no problem appears.

        To make daytrader running under Full EJB3 runtime mode with FK constraints created status, the @OneToOne relationship should be removed, and consequently a named query(which is never used) should be removed.

        Of cause, my previous patch is not complete, I will attach a new one for this fix.

        Please let me know if any question about this issue. thanks!

        Show
        Forrest Xia added a comment - Hi David, The problem this patch tends to fix is not about OpenJPA database support issue or any database vendor bug. I think it's a daytrader bug. Here is my finding: By default, OpenJPA won't generate FK constraints, even you use a config property like this: <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> So using Geronimo to run daytrader, the EJB3 annotation defined relationships(FKs) will never be created by OpenJPA on tables, unless you add another OpenJPA config property like this: <property name="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=restrict,JoinForeignKeyDeleteAction=restrict"/> But when I am doing a migration to JBoss 5, which uses Hibernate as JPA provider, I used a hibernate config property like this: <property name="hibernate.hbm2ddl.auto" value="update"/> Hibernate will generate DDL according to EJB3 annotations in daytrader entity beans, and create FKs constraints on tables. Then when doing a sell operation in Full EJB3 runtime mode, an exception will be thrown: 2009-01-07 23:58:25,323 DEBUG [org.hibernate.util.JDBCExceptionReporter] (http-127.0.0.1-8080-1) could not delete: org.apache.geronimo.samples.daytrader.HoldingDataBean#1001 [delete from holdingejb where HOLDINGID=?] com.ibm.db2.jcc.b.lm: DB2 SQL Error: SQLCODE=-532, SQLSTATE=23504, SQLERRMC=DB2ADMIN.ORDEREJB.FK4992164F3AE187D6, DRIVER=3.50.152 at com.ibm.db2.jcc.b.wc.a(wc.java:575) at com.ibm.db2.jcc.b.wc.a(wc.java:57) at com.ibm.db2.jcc.b.wc.a(wc.java:126) ... The FK4992164F3AE187D6 is from annotated relationship on OrderDataBean property @OneToOne(fetch=FetchType.LAZY) @JoinColumn(name = "HOLDING_HOLDINGID") private HoldingDataBean holding; It stop deleting any holdings from holdingejb table, thus cause sell operation failed. For DIRECT runtime mode, the FK constraints will never be created, so no problem appears. To make daytrader running under Full EJB3 runtime mode with FK constraints created status, the @OneToOne relationship should be removed, and consequently a named query(which is never used) should be removed. Of cause, my previous patch is not complete, I will attach a new one for this fix. Please let me know if any question about this issue. thanks!
        Hide
        Forrest Xia added a comment -

        patch available, please review and help commit, thanks!

        Show
        Forrest Xia added a comment - patch available, please review and help commit, thanks!
        Hide
        Donald Woods added a comment -

        Is this patch for daytrader/branches/2.1 or daytrader/trunk?

        Show
        Donald Woods added a comment - Is this patch for daytrader/branches/2.1 or daytrader/trunk?
        Hide
        David Jencks added a comment -

        If you mark this closed you can be pretty certain that no one will look at or apply your patch.

        I'd prefer to see an explanation of why removing this relationship results in a more correct data model and demonstration that it doesn't work on other dbs as well. If the operation only fails on db2 I'd suspect a bug in the db2 support in openjpa which is not something we should alter the data model for.

        Show
        David Jencks added a comment - If you mark this closed you can be pretty certain that no one will look at or apply your patch. I'd prefer to see an explanation of why removing this relationship results in a more correct data model and demonstration that it doesn't work on other dbs as well. If the operation only fails on db2 I'd suspect a bug in the db2 support in openjpa which is not something we should alter the data model for.
        Hide
        Forrest Xia added a comment -

        Please someone can help commit this patch to svn. thanks!

        Show
        Forrest Xia added a comment - Please someone can help commit this patch to svn. thanks!
        Hide
        Forrest Xia added a comment -

        Remove @OneToOne relationship to HoldingDataBean.

        Let me know if there is a better solution for this issue. thanks!

        Show
        Forrest Xia added a comment - Remove @OneToOne relationship to HoldingDataBean. Let me know if there is a better solution for this issue. thanks!

          People

          • Assignee:
            Donald Woods
            Reporter:
            Forrest Xia
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development