2 Replies Latest reply on Nov 25, 2002 3:14 AM by jevoskuil

    transactions, Oracle, CMP-relations

    jevoskuil

      I have three CMP2 entity beans: a profile entity, which may have zero or more address entities, and zero or more custom attribute entities.

      I have a host of test cases written, which add and remove addresses and attributes from profiles. All works fine on JBoss with MySql. When I change the database to Oracle8, some (but not all) test cases cause exceptions. A typical stack trace, preceded by some debug messages from the CMP engine, is appended below. I also appended the relationships-element from jbosscmp-jdbc.xml.

      What is striking is that the error has to do with writing a blob to the database. I know that there are or at least have been problems with blobs and Oracle. But my beans don't have blob fields at all, only longs and strings. Could it be that the transaction manager tries to write byte arrays to the database?

      An important detail may be that I use the facade pattern. When a profile value object arrives at the facade, that may result in multiple addresses or attributes being added or removed. Could it be that affecting more than one row per table in one transaction is bad?

      Any help would be appreciated. TIA, --Jan


      13:52:17,218 DEBUG [findByPrimaryKey] Executing SQL: SELECT profileId FROM AN_PROFILE WHERE profileId=?
      13:52:17,218 DEBUG [anachron_ProfileEntity] Executing SQL: SELECT firstName, lastName, prepositionalPart, email, phone, acceptTermsDate, currencyCode, languageCode, countryCode, localVariantCode, creationTime, lastModified, defaultAddressPK FROM AN_PROFILE WHERE (profileId=?)
      13:52:17,234 DEBUG [anachron_ProfileEntity] Executing SQL: SELECT profileId, addressId FROM AN_ADDRESS WHERE (profileId_FK=?)
      13:52:17,234 DEBUG [anachron_AddressEntity] Executing SQL: SELECT profileId, addressId,addressItem1, addressItem2, addressItem3, addressItem4, addressItem5, street, houseNumber, houseNumberAddition, region, city, country, countryCode, postalCode FROM AN_ADDRESS WHERE (profileId=? AND addressId=?) OR (profileId=? AND addressId=?)
      13:52:17,250 DEBUG [anachron_ProfileEntity] Executing SQL: SELECT profileId, attributeName FROM AN_PROFILE_ATTRIBUTE WHERE (profileId_FK=?)
      13:52:17,265 DEBUG [findByPrimaryKey] Executing SQL: SELECT profileId FROM AN_PROFILE WHERE profileId=?
      13:52:17,281 DEBUG [anachron_ProfileEntity] Executing SQL: SELECT firstName, lastName, prepositionalPart, email, phone, acceptTermsDate, currencyCode, languageCode, countryCode, localVariantCode, creationTime, lastModified, defaultAddressPK FROM AN_PROFILE WHERE (profileId=?)
      13:52:17,281 DEBUG [anachron_ProfileEntity] Executing SQL: UPDATE AN_PROFILE SET lastModified=?, defaultAddressPK=? WHERE profileId=?


      *** here the trouble starts ***

      13:52:17,296 ERROR

      [GlobalTxEntityMap]
      Store failed on entity: -6397208899534309423
      javax.ejb.EJBException: Store failed;
      CausedByException is: org.jboss.ejb.plugins.cmp.jdbc.ByteArrayBlob
      at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreEntityCommand.execute(JDBCStoreEntityCommand.java:94)
      at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.storeEntity(JDBCStoreManager.java:589)
      at org.jboss.ejb.plugins.CMPPersistenceManager.storeEntity(CMPPersistenceManager.java:458)
      at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.storeEntity(CachedConnectionInterceptor.java:388)
      at org.jboss.ejb.EntityContainer.storeEntity(EntityContainer.java:705)
      at org.jboss.ejb.GlobalTxEntityMap.syncEntities(GlobalTxEntityMap.java:99)
      at org.jboss.ejb.GlobalTxEntityMap$GlobalTxEntityMapCleanup.beforeCompletion(GlobalTxEntityMap.java:168)
      at org.jboss.tm.TxCapsule.doBeforeCompletion(TxCapsule.java:1362)
      at org.jboss.tm.TxCapsule.commit(TxCapsule.java:332)
      at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:73)
      at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:201)
      at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:60)
      at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:130)
      at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:203)
      at org.jboss.ejb.StatelessSessionContainer.invoke(StatelessSessionContainer.java:313)
      at org.jboss.ejb.Container.invoke(Container.java:720)
      at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:517)
      at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:370)
      at java.lang.reflect.Method.invoke(Native Method)
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)
      at sun.rmi.transport.Transport$1.run(Transport.java:152)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:148)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:465)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:706)
      at java.lang.Thread.run(Thread.java:484)java.lang.ClassCastException: org.jboss.ejb.plugins.cmp.jdbc.ByteArrayBlob
      at oracle.jdbc.driver.OraclePreparedStatement.setBlob(OraclePreparedStatement.java:1500)
      at org.jboss.resource.adapter.jdbc.local.LocalPreparedStatement.setBlob(LocalPreparedStatement.java:680)
      at org.jboss.ejb.plugins.cmp.jdbc.JDBCUtil.setParameter(JDBCUtil.java:221)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMPFieldBridge.setArgumentParameters(JDBCAbstractCMPFieldBridge.java:283)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMPFieldBridge.setInstanceParameters(JDBCAbstractCMPFieldBridge.java:262)
      at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreEntityCommand.execute(JDBCStoreEntityCommand.java:85)
      at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.storeEntity(JDBCStoreManager.java:589)
      at org.jboss.ejb.plugins.CMPPersistenceManager.storeEntity(CMPPersistenceManager.java:458)
      at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.storeEntity(CachedConnectionInterceptor.java:388)
      at org.jboss.ejb.EntityContainer.storeEntity(EntityContainer.java:705)
      at org.jboss.ejb.GlobalTxEntityMap.syncEntities(GlobalTxEntityMap.java:99)
      at org.jboss.ejb.GlobalTxEntityMap$GlobalTxEntityMapCleanup.beforeCompletion(GlobalTxEntityMap.java:168)
      at org.jboss.tm.TxCapsule.doBeforeCompletion(TxCapsule.java:1362)
      at org.jboss.tm.TxCapsule.commit(TxCapsule.java:332)
      at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:73)
      at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:201)
      at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:60)
      at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:130)
      at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:203)
      at org.jboss.ejb.StatelessSessionContainer.invoke(StatelessSessionContainer.java:313)
      at org.jboss.ejb.Container.invoke(Container.java:720)
      at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:517)
      at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:370)
      at java.lang.reflect.Method.invoke(Native Method)
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)
      at sun.rmi.transport.Transport$1.run(Transport.java:152)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:148)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:465)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:706)
      at java.lang.Thread.run(Thread.java:484)



      *** Definition of the relationships:



      <ejb-relation>

      <ejb-relation-name>profile-address</ejb-relation-name>
      <foreign-key-mapping/>

      <ejb-relationship-role>
      <ejb-relationship-role-name>profile-has-addresses</ejb-relationship-role-name>
      <key-fields>
      <key-field>
      <field-name>profileId</field-name> <!-- field in ProfileEJB -->
      <column-name>profileId_FK</column-name> <!-- column in address-table -->
      </key-field>
      </key-fields>

      </ejb-relationship-role>

      <ejb-relationship-role>
      <ejb-relationship-role-name>address-belongs-to-profile</ejb-relationship-role-name>
      <key-fields/>
      </ejb-relationship-role>

      </ejb-relation>

      <ejb-relation>

      <ejb-relation-name>profile-attribute</ejb-relation-name>
      <foreign-key-mapping/>

      <ejb-relationship-role>
      <ejb-relationship-role-name>profile-has-attributes</ejb-relationship-role-name>

      <key-fields>
      <key-field>
      <field-name>profileId</field-name>
      <column-name>profileId_FK</column-name>
      </key-field>
      </key-fields>

      </ejb-relationship-role>

      <ejb-relationship-role>
      <ejb-relationship-role-name>attribute-belongs-to-profile</ejb-relationship-role-name>
      <key-fields/>
      </ejb-relationship-role>
      </ejb-relation>

        • 1. Re: transactions, Oracle, CMP-relations
          scoy

          Hi!

          I think your problem is a combination of issues.

          1. The standard Oracle 8 data mapping for java.lang.Object is BLOB (see conf/standardjbosscmp-jdbc.xml).

          2. Blobs do not work for Oracle in JBoss versions prior to 3.0.4.

          Somewhere, you are trying to write an object that does not have a data mapping, so JBoss is falling back to java.lang.Object.

          Oracle blobs work in JBoss 3.0.4, but I think you want to track down which column it's trying store as a BLOB and map it more appropriately. Looking at the table that Oracle created should provide some clues in that area.

          Steve

          • 2. Re: transactions, Oracle, CMP-relations
            jevoskuil

            Steve, thank you for your help. Yes, there was a blob after all: the profile has as one of its attributes a default address, implemented as the AddressPK. This class gets interpreted as columns in the Address entity, but the Profile entity of course doesn't realize it is a PK object in the first place... Thanks again, -j