5 Replies Latest reply on May 24, 2002 4:41 PM by Olaf Bergner

    JBoss 3.0RC3 CMP 2.0: java.lang.IllegalStateException: remov

    Olaf Bergner Newbie

      Hello,

      this is my first attempt at EJB, trying to follow Richard Monson-Haefel's book. I am stuck with the One-to-One Bidirectional Relationship (CMR) involving a customer bean and a credit card bean.The underlying database is PostgreSQL.

      In my table layout, I have a column "credit_card_id" pointing from the customer table to the credit card table and a column "customer_id" pointing from the credit card table to the customer table.

      Deployment went just fine (after a while;)), so I wrote a simple test client that creates a customer bean and calls setCreditCardDO(creditCardDO) on the customer.

      The result looks as follows:

      18:24:45,676 ERROR [LogInterceptor] TransactionRolledbackException, causedBy:
      java.lang.IllegalStateException: removing bean lock and it has tx set!
      at org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.removeRef(QueuedPessimisticEJBLock.java:469)
      at org.jboss.ejb.BeanLockManager.removeLockRef(BeanLockManager.java:78)
      at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:124)
      at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:69)
      at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:96)
      at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:167)
      at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:61)
      at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:129)
      at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166)
      at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:493)
      at org.jboss.ejb.plugins.local.BaseLocalContainerInvoker.invoke(BaseLocalContainerInvoker.java:296)
      at org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:38)
      at $Proxy39.getPrimaryKey(Unknown Source)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.setInstanceValue(JDBCCMRFieldBridge.java:625)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.setValue(JDBCCMRFieldBridge.java:563)
      at org.jboss.ejb.plugins.cmp.bridge.EntityBridgeInvocationHandler.invoke(EntityBridgeInvocationHandler.java:125)
      at org.jboss.proxy.compiler.Runtime.invoke(Runtime.java:59)
      at com.titan.customer.CustomerBean$Proxy.setCreditCard()
      at com.titan.customer.CustomerBean.setCreditCardDO(CustomerBean.java:248)
      at java.lang.reflect.Method.invoke(Native Method)
      at org.jboss.ejb.EntityContainer$ContainerInterceptor.invoke(EntityContainer.java:1197)
      at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:190)
      at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:340)
      at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:147)
      at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:193)
      at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:107)
      at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:69)
      at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:96)
      at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:167)
      at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:61)
      at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:129)
      at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166)
      at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:493)
      at org.jboss.ejb.Container.invoke(Container.java:705)
      at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:1055)
      at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:491)
      at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:364)
      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)

      The PostgreSQL logfile says:

      DEBUG: query: SELECT COUNT(*) FROM customer WHERE ID=2
      DEBUG: query: INSERT INTO customer (ID, last_name, first_name, credit_card_id) VALUES (2, null, null, null)
      DEBUG: query: commit;begin;
      DEBUG: ProcessUtility: commit;begin;
      DEBUG: ProcessUtility: commit;begin;
      DEBUG: query: SELECT last_name, first_name, credit_card_id FROM customer WHERE (ID=2)
      DEBUG: query: SELECT COUNT(*) FROM credit_card WHERE ID=null
      DEBUG: query: INSERT INTO credit_card (ID, exp_date, number, name, organization, customer_id) VALUES (null, '1010 Colorado', 'Austin', 'TX', '78701', null)
      DEBUG: query: SELECT $1 IS NULL
      DEBUG: query: SELECT -1
      DEBUG: query: rollback; begin;
      DEBUG: ProcessUtility: rollback; begin;
      DEBUG: ProcessUtility: rollback; begin;

      This is the relevant part of my ejb-jar.xml:

      (CustomerEJB)

      <ejb-name>CustomerEJB</ejb-name>
      com.titan.customer.CustomerHomeRemote
      com.titan.customer.CustomerRemote
      <local-home>com.titan.customer.CustomerHomeLocal</local-home>
      com.titan.customer.CustomerLocal
      <ejb-class>com.titan.customer.CustomerBean</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.Integer</prim-key-class>
      False
      <cmp-version>2.x</cmp-version>
      <abstract-schema-name>Customer</abstract-schema-name>
      <cmp-field>
      <field-name>ID</field-name>
      </cmp-field>
      <cmp-field>
      <field-name>lastName</field-name>
      </cmp-field>
      <cmp-field>
      <field-name>firstName</field-name>
      </cmp-field>
      <primkey-field>ID</primkey-field>
      <ejb-local-ref>
      <ejb-ref-name>ejb/CreditCardHomeLocal</ejb-ref-name>
      <ejb-ref-type>Entity</ejb-ref-type>
      <local-home>com.titan.creditcard.CreditCardHomeLocal</local-home>
      com.titan.creditcard.CreditCardLocal
      <ejb-link>CreditCardEJB</ejb-link>
      </ejb-local-ref>
      <security-identity><use-caller-identity/></security-identity>


      (CreditCardEJB)

      <ejb-name>CreditCardEJB</ejb-name>
      <local-home>com.titan.creditcard.CreditCardHomeLocal</local-home>
      com.titan.creditcard.CreditCardLocal
      <ejb-class>com.titan.creditcard.CreditCardBean</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.Integer</prim-key-class>
      False
      <cmp-version>2.x</cmp-version>
      <abstract-schema-name>CreditCard</abstract-schema-name>
      <cmp-field>
      <field-name>ID</field-name>
      </cmp-field>
      <cmp-field>
      <field-name>expirationDate</field-name>
      </cmp-field>
      <cmp-field>
      <field-name>number</field-name>
      </cmp-field>
      <cmp-field>
      <field-name>nameOnCard</field-name>
      </cmp-field>
      <cmp-field>
      <field-name>creditOrganization</field-name>
      </cmp-field>
      <primkey-field>ID</primkey-field>
      <security-identity><use-caller-identity/></security-identity>


      (Relationships)
      <ejb-relation>
      <ejb-relation-name>Customer-CreditCard</ejb-relation-name>
      <ejb-relationship-role>
      <ejb-relationship-role-name>Customer-owns-a-CreditCard</ejb-relationship-role-name>
      One
      <relationship-role-source>
      <ejb-name>CustomerEJB</ejb-name>
      </relationship-role-source>
      <cmr-field>
      <cmr-field-name>creditCard</cmr-field-name>
      </cmr-field>
      </ejb-relationship-role>
      <ejb-relationship-role>
      <ejb-relationship-role-name>CreditCard-is-owned-by-Customer</ejb-relationship-role-name>
      One
      <relationship-role-source>
      <ejb-name>CreditCardEJB</ejb-name>
      </relationship-role-source>
      <cmr-field>
      <cmr-field-name>customer</cmr-field-name>
      </cmr-field>
      </ejb-relationship-role>
      </ejb-relation>

      The corresponding parts from jbosscmp-jdbc.xml:

      (CustomerEJB)

      <ejb-name>CustomerEJB</ejb-name>
      <table-name>customer</table-name>
      <cmp-field>
      <field-name>ID</field-name>
      <column-name>ID</column-name>
      </cmp-field>
      <cmp-field>
      <field-name>lastName</field-name>
      <column-name>last_name</column-name>
      </cmp-field>
      <cmp-field>
      <field-name>firstName</field-name>
      <column-name>first_name</column-name>
      </cmp-field>


      (CreditCardEJB)

      <ejb-name>CreditCardEJB</ejb-name>
      <table-name>credit_card</table-name>
      <cmp-field>
      <field-name>ID</field-name>
      <column-name>ID</column-name>
      </cmp-field>
      <cmp-field>
      <field-name>expirationDate</field-name>
      <column-name>exp_date</column-name>
      </cmp-field>
      <cmp-field>
      <field-name>number</field-name>
      <column-name>number</column-name>
      </cmp-field>
      <cmp-field>
      <field-name>nameOnCard</field-name>
      <column-name>name</column-name>
      </cmp-field>
      <cmp-field>
      <field-name>creditOrganization</field-name>
      <column-name>organization</column-name>
      </cmp-field>


      (Relationships)
      <ejb-relation>
      <ejb-relation-name>Customer-CreditCard</ejb-relation-name>
      <ejb-relationship-role>
      <ejb-relationship-role-name>Customer-owns-a-CreditCard</ejb-relationship-role-name>
      <key-fields>
      <key-field>
      <field-name>ID</field-name>
      <column-name>customer_id</column-name>
      </key-field>
      </key-fields>
      </ejb-relationship-role>
      <ejb-relationship-role>
      <ejb-relationship-role-name>CreditCard-is-owned-by-Customer</ejb-relationship-role-name>
      <key-fields>
      <key-field>
      <field-name>ID</field-name>
      <column-name>credit_card_id</column-name>
      </key-field>
      </key-fields>
      </ejb-relationship-role>
      </ejb-relation>

      Sorry for the long read, but I have been stuck with this problem for three days (and nights), and I wanted to provide as much information as possible.

      Since the exception implies a transactional problem I should add that the transactional attribute of every method involved is set to "Required". Yet somehow I doubt this is a problem with the transactional context.

      I had no (severe) problems establishing the One-to-One Unidirectional Relationship between a customer and his address, using a link table. Does this imply that I am not a complete moron?

      Any help would be greatly appreciated.

      Thanks,
      Olaf

        • 1. Re: JBoss 3.0RC3 CMP 2.0: java.lang.IllegalStateException: r
          bjoern Newbie

          Hi Olaf!

          I have exactly the same problem as you. I try to solve it about four days from now and at my posting a few days befor was not replyed.
          I hope some GURUS would know what we can do to get the relationship working.
          By the way, I'm using a Oracle 9i Database

          CU
          Bj

          • 2. Re: JBoss 3.0RC3 CMP 2.0: java.lang.IllegalStateException: r
            bjoern Newbie

            Hi All!

            I finaly solved the problem!

            Check your sourcecode if in the entity beans and session beans the ejb* Methodes are implemented.

            It should look like this in the implementation class:

            Entity Bean:
            public void ejbCreate() {}
            public void ejbPostCreate() {}
            public void ejbActivate() {}
            public void ejbPassivate() {}
            public void ejbLoad() {}
            public void ejbRemove() {}
            public void ejbStore() {}
            public void setEntityContext(EntityContext ctx) {}
            public void unsetEntityContext() {}

            Session Bean:
            public void ejbRemove() {}
            public void ejbActivate() {}
            public void ejbPassivate() {}
            public void setSessionContext(SessionContext ctx) {}
            public void ejbCreate() {}

            Even you do not need them you must have this methodes in your code and implement them at least with {}.

            Hope it helps, write if it works at your code

            CU
            BJ

            • 3. Re: JBoss 3.0RC3 CMP 2.0: java.lang.IllegalStateException: r
              Olaf Bergner Newbie

              Hi BJ,

              many thanks for your kind reply, but unfortunately this won't solve my problem. In my entity beans, all those life cycle methods are present, though their implementatin is indeed mostly empty.

              I have been trying hard to solve the problem, squashing a minor bug in jbosscmp-jdbc.xml (I forgot the <foreign-key-mapping/> tag, but jboss seems to imply it by default). Finally I changed the database layout, switching to a link table for the customer and credit card tables, adjusting jbosscmp-jdbc.xml accordingly. Thus far to no avail.

              What puzzles me most, especially since switching to the new database layout, is that to me there seems to be no major difference between my working one-to-one unidirectional relationship between the CustomerBean and the AddressBean and the one-to-one bidirectional relationship between the CustomerBean and the CreditCardBean. What's more, judging from the postgres log, there is no problem internal to the database.

              I have been searching these forums and the internet for a solution, but the few information I found didn't help.

              Anyways, thanks for your reply.

              Regards,
              Olaf

              • 4. Re: JBoss 3.0RC3 CMP 2.0: java.lang.IllegalStateException: r
                Olaf Bergner Newbie

                Hello,

                well, I didn't find a solution, but a workaround. I adjusted the CreditCardBean's ejbCreate() method so that it takes an Integer ID as its first argument. In the CustomerBean's setCreditCardDO() method, if the bean does not already have a credit card associated it passes IT'S OWN PRIMARY KEY to the CreditCardLocaHome's create() method (I know this is ugly, don't blame me). Now everything is working just fine. Within the narrow confines of such an ugly architecture, that is.

                Originally, I was trying to get around this, by using an insert-update-trigger on the credit card table, setting the primary key to a special, non-null value (-1) as suggested by a posting elsewhere on this list. However, this didn't work out for me.

                One question that springs to my mind: does this behavior imply that an entity bean that is created with a primary key value of null leaves the transactional context under which it was created? Just curious here, hope someone can answer my question.

                Regards,
                Olaf

                • 5. Re: JBoss 3.0RC3 CMP 2.0: java.lang.IllegalStateException: r
                  Olaf Bergner Newbie

                  As an afterthought: such a behaviour would in fact seem quite sensible. How were the container to know that the bean thus created would be granted a 'proper' primary key through other means, e.g. a database trigger? And just in case the transaction had to be rolled back, how were the container to identify all beans involved if one or more did not have a proper primary key? This assumes, of course, that the container does not have other means of identifying beans apart from their primary keys, e.g. holding a reference to them.

                  Regards,

                  Olaf