6 Replies Latest reply on Mar 3, 2002 4:42 PM by Dain Sundstrom

    got IllegalStateException in a place that maybe valid

    Thomas Phan Newbie

      I got the following exception:

      java.lang.IllegalStateException: A CMR field cannot be set or added to a relationship in ejbCreate; this should be done in the ejbPostCreate method instead [EJB 2.0 Spec. 10.5.2].
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.addRelation(JDBCCMRFieldBridge.java:749)
      at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:146)
      at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:296)
      at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:189)
      at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:108)
      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:127)
      at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166)
      at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:475)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.invokeAddRelation(JDBCCMRFieldBridge.java:682)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.createRelationLinks(JDBCCMRFieldBridge.java:609)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.add(RelationSet.java:89)
      at esb.ejb.UserBean.addRole(Unknown Source)
      at esb.ejb.UserBean.setRoleData(Unknown Source)

      And I'm not calling the add/set code in ejbCreate. Seems that this is a check in the JBoss code; does this a case that the check code misses a condition? Or the join-table (i.e. the extra table for many-to-many)'s ejbCreate causes this exception?

      my class has:
      /**
      * @ejb:relation name="user-role" role-name="many-users-have-many-roles" target-ejb="Role" target-role-name="many-roles-have-many-users" target-multiple="yes"
      * @ejb:interface-method view-type="local"
      *
      * @jboss:relation fk-constraint="true" related-pk-field="roleId" fk-column="roleId"
      * @jboss:target-relation fk-constraint="true" related-pk-field="userId" fk-column="userId"
      * @jboss:relation-table table-name="UserRole" create-table="true" remove-table="false"
      */
      public abstract Collection getRoles();
      /**
      * @ejb:interface-method view-type="local"
      */
      public abstract void setRoles(Collection roles);
      /**
      * @ejb:interface-method view-type="local"
      */
      public void addRole(esb.interfaces.RoleLocal role) {
      getRoles().add(role);
      }
      /**
      * @ejb:interface-method view-type="local"
      */
      public void setRoleData(Collection roles) throws Exception {
      esb.interfaces.RoleLocalHome roleLocalHome = getRoleLocalHome();
      getRoles().clear();
      for (Iterator i = roles.iterator(); i.hasNext();) {
      addRole(roleLocalHome.findByPrimaryKey(((esb.interfaces.RoleData) i.next()).getRoleId()));
      }
      }

        • 1. Re: got IllegalStateException in a place that maybe valid
          Dain Sundstrom Master

          I need a little more of the stack trace. It looks like you are calling userBean.setRoleData in the ejbCreate of user. Both sides of the relationship must have completed ejbCreated, before a relationship can be created.

          • 2. Re: got IllegalStateException in a place that maybe valid
            Thomas Phan Newbie

            02:25:32,279 ERROR [LogInterceptor] TransactionRolledbackException, causedBy:
            java.lang.IllegalStateException: A CMR field cannot be set or added to a relationship in ejbCreate; this should be done in the ejbPostCreate method instead [EJB 2.0 Spec. 10.5.2].
            at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.addRelation(JDBCCMRFieldBridge.java:749)
            at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:146)
            at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:296)
            at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:189)
            at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:108)
            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:127)
            at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166)
            at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:475)
            at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.invokeAddRelation(JDBCCMRFieldBridge.java:682)
            at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.createRelationLinks(JDBCCMRFieldBridge.java:609)
            at org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.add(RelationSet.java:89)
            at esb.ejb.UserBean.addRole(Unknown Source)
            at esb.ejb.UserBean.setRoleData(Unknown Source)
            at java.lang.reflect.Method.invoke(Native Method)
            at org.jboss.ejb.EntityContainer$ContainerInterceptor.invoke(EntityContainer.java:1127)
            at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:184)
            at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:296)
            at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:189)
            at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:108)
            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:127)
            at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166)
            at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:475)
            at org.jboss.ejb.plugins.local.BaseLocalContainerInvoker.invoke(BaseLocalContainerInvoker.java:308)
            at org.jboss.ejb.plugins.local.BaseLocalContainerInvoker$EntityProxy.invoke(BaseLocalContainerInvoker.java:412)
            at $Proxy22.setRoleData(Unknown Source)
            at esb.ejb.UserFacadeBean.setUser(Unknown Source)
            at java.lang.reflect.Method.invoke(Native Method)
            at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:642)
            at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:77)
            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:127)
            at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166)
            at org.jboss.ejb.StatelessSessionContainer.invoke(StatelessSessionContainer.java:308)
            at org.jboss.ejb.Container.invoke(Container.java:630)
            at com.sun.management.jmx.MBeanServerImpl.invoke(MBeanServerImpl.java:1555)
            at com.sun.management.jmx.MBeanServerImpl.invoke(MBeanServerImpl.java:1523)
            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:142)
            at java.security.AccessController.doPrivileged(Native Method)
            at sun.rmi.transport.Transport.serviceCall(Transport.java:139)
            at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)
            at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)
            at java.lang.Thread.run(Thread.java:484)
            02:25:32,288 ERROR [LogInterceptor] TransactionRolledbackException, causedBy:

            public abstract class UserBean implements EntityBean {
            /**
            * @ejb:create-method
            * @ejb:permission role-name="Administrator"
            */
            public String ejbCreate(String userId, String password) throws CreateException {
            setUserId(userId);
            setPassword(password);
            return null;
            }
            /**
            * @ejb:create-method
            * @ejb:permission role-name="Administrator"
            */
            public String ejbCreate(String userId, String password, Collection roles, Collection groups, esb.interfaces.ProfileData profileData) throws CreateException {
            return ejbCreate(userId, password);
            }
            public void ejbPostCreate(String userId, String password) throws CreateException {
            }
            public void ejbPostCreate(String userId, String password, Collection roles, Collection groups, esb.interfaces.ProfileData profileData) throws CreateException {
            try {
            setRoleData(roles);
            setGroupData(groups);
            setProfileData(profileData);
            }
            catch (Exception e) { throw new CreateException(e.toString()); }
            }

            public abstract class RoleBean implements EntityBean {
            /**
            * @ejb:create-method
            * @ejb:permission role-name="Administrator"
            */
            public String ejbCreate(String roleId, String description) throws CreateException {
            setRoleId(roleId);
            setDescription(description);
            return null;
            }
            public void ejbPostCreate(String roleId, String description) throws CreateException {
            }

            Note: My profile bean (one-to-one) works

            • 3. Re: got IllegalStateException in a place that maybe valid
              Dain Sundstrom Master

              If you are sure that all all beans have completed ejbCreate, post a simple bug report with a small test cast at sourceforge.

              • 4. Re: got IllegalStateException in a place that maybe valid
                Thomas Phan Newbie

                Hi, I reported the above bug to http://sourceforge.net/tracker/index.php?func=detail&aid=523560&group_id=22866&atid=376685

                And I changed my code and found another problem

                my code:
                public void setRoleData(Collection roles) throws Exception {
                esb.interfaces.RoleLocalHome roleLocalHome = getRoleLocalHome();
                ArrayList al = new ArrayList();
                System.out.println("0");
                for (Iterator i = roles.iterator(); i.hasNext();) {
                al.add(roleLocalHome.findByPrimaryKey(((esb.interfaces.RoleData) i.next()).getRoleId()));
                }
                for (Iterator i = al.iterator(); i.hasNext();) {
                System.out.println("[" + ((esb.interfaces.RoleLocal) i.next()).getRoleId() + "]");
                }
                Collection c = getRoles();
                System.out.println("al.size(): " + al.size());
                System.out.println("1");
                c.clear();
                System.out.println("2");
                c.addAll(al);
                System.out.println("3");
                }

                console output:
                01:09:31,587 INFO [Default] 0
                01:09:31,597 INFO [Default] [Administrator] <- a role that I want to relate to the current user
                01:09:31,600 INFO [Default] [guess] <- a role that I want to relate to the current user
                01:09:31,604 INFO [Default] al.size(): 2
                01:09:31,604 INFO [Default] 1
                01:09:31,618 INFO [Default] 2
                <the transaction hangs here, and locks all related rows, then wait for a long time>
                javax.transaction.TransactionRolledbackException: Transaction marked for rollback, possibly a timeout; nested exception is:
                java.lang.RuntimeException: Transaction marked for rollback, possibly a timeout
                java.lang.RuntimeException: Transaction marked for rollback, possibly a timeout
                at org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock.waitForTx(QueuedPessimisticEJBLock.java:305)

                debug output (SQL only):
                2002-03-04 01:09:31,582 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCLoadEntityCommand.User] Executing SQL: SELECT password FROM User WHERE (userId=?)
                2002-03-04 01:09:31,589 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCFindByPrimaryKeyQuery.Role.findByPrimaryKey] Executing SQL: SELECT roleId FROM Role WHERE roleId=?
                2002-03-04 01:09:31,593 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCLoadEntityCommand.Role] Executing SQL: SELECT roleId,description FROM Role WHERE (roleId=?) OR (roleId=?)
                2002-03-04 01:09:31,598 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCLoadEntityCommand.Role] Executing SQL: SELECT description FROM Role WHERE (roleId=?)
                2002-03-04 01:09:31,601 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCLoadRelationCommand.User] Executing SQL: SELECT roleId FROM UserRole WHERE (userId=?)
                2002-03-04 01:09:31,606 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCLoadRelationCommand.Role] Executing SQL: SELECT roleId, userId FROM UserRole WHERE (roleId=?) OR (roleId=?)

                database data remains the same (i.e. no delete and no add)

                • 5. Re: got IllegalStateException in a place that maybe valid
                  Thomas Phan Newbie

                  For more info:

                  CREATE TABLE Communication(
                  communicationId INT NOT NULL,
                  PRIMARY KEY (communicationId));

                  CREATE TABLE BusinessUnit(
                  businessUnitId INT NOT NULL,
                  name VARCHAR(255),
                  type VARCHAR(255),
                  description VARCHAR(255),
                  communicationId INT, <- foreign key
                  addressId INT,
                  parentId INT,
                  PRIMARY KEY (businessUnitId));

                  -----
                  public abstract class BusinessUnitBean implements EntityBean {
                  ...
                  // business method
                  public void setCommunicationId(int communicationId) throws FinderException {
                  try { setCommunication(getCommunicationLocalHome().findByPrimaryKey(new Integer(communicationId))); }
                  catch (NamingException ne) { throw new FinderException(ne.toString()); }
                  }
                  }
                  ^^
                  take an example:
                  businessUnitId = 5
                  set communicationId from 3 to 6

                  If I'm in setCommunicationId(), BusinessUnitBean must hold a row, i.e. 5 with communicationId=3. I now call setCommunicationId(6) from a facade bean

                  -----
                  # tail -f /var/jboss-3.0.0beta/log/server.log | egrep 'SQL|Set'
                  2002-03-04 01:43:41,722 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCFindByPrimaryKeyQuery.BusinessUnit.findByPrimaryKey] Executing SQL: SELECT businessUnitId FROM BusinessUnit WHERE businessUnitId=?
                  2002-03-04 01:43:41,722 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCFindByPrimaryKeyQuery.BusinessUnit.findByPrimaryKey] Set parameter: index=1, jdbcType=INTEGER, value=3

                  +----------------+
                  | businessUnitId |
                  +----------------+
                  | 3 |
                  +----------------+

                  2002-03-04 01:43:41,726 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCLoadEntityCommand.BusinessUnit] Executing SQL: SELECT businessUnitId,name, type, description, parentId, addressId, communicationId FROM BusinessUnit WHERE (businessUnitId=?) OR (businessUnitId=?)
                  2002-03-04 01:43:41,726 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMP2xFieldBridge.BusinessUnit.businessUnitId] Set parameter: index=1, jdbcType=INTEGER, value=3
                  2002-03-04 01:43:41,726 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMP2xFieldBridge.BusinessUnit.businessUnitId] Set parameter: index=2, jdbcType=INTEGER, value=5

                  +----------------+-------------------+-------------+------------------+----------+-----------+-----------------+
                  | businessUnitId | name | type | description | parentId | addressId | communicationId |
                  +----------------+-------------------+-------------+------------------+----------+-----------+-----------------+
                  | 3 | Entersys | limited | Entersys Limited | 0 | 4 | 3 | <- it'll change to 6
                  | 5 | Entersys Software | corporation | Entersys Limited | 0 | 5 | 6 |
                  +----------------+-------------------+-------------+------------------+----------+-----------+-----------------+

                  2002-03-04 01:43:41,754 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCFindByPrimaryKeyQuery.Communication.findByPrimaryKey] Executing SQL: SELECT communicationId FROM Communication WHERE communicationId=?
                  2002-03-04 01:43:41,754 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCFindByPrimaryKeyQuery.Communication.findByPrimaryKey] Set parameter: index=1, jdbcType=INTEGER, value=6

                  +-----------------+
                  | communicationId |
                  +-----------------+
                  | 6 |
                  +-----------------+

                  2002-03-04 01:43:41,758 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCLoadRelationCommand.Communication] Executing SQL: SELECT businessUnitId FROM BusinessUnit WHERE (communicationId=?)
                  2002-03-04 01:43:41,758 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMP2xFieldBridge.BusinessUnit.communicationId] Set parameter: index=1, jdbcType=INTEGER, value=3
                  2002-03-04 01:43:41,775 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreEntityCommand.BusinessUnit] Executing SQL: UPDATE BusinessUnit SET communicationId=? WHERE businessUnitId=?
                  2002-03-04 01:43:41,775 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMP2xFieldBridge.BusinessUnit.communicationId] Set parameter: index=1, jdbcType=INTEGER, value=6
                  2002-03-04 01:43:41,775 DEBUG [org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMP2xFieldBridge.BusinessUnit.businessUnitId] Set parameter: index=2, jdbcType=INTEGER, value=3

                  Seems ok, but there'r expections going on (pls compare the time with above)

                  # cat /var/jboss-3.0.0beta/log/server.log | egrep '43:.*ERROR'
                  2002-03-04 01:43:41,762 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy:
                  2002-03-04 01:43:41,768 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy:
                  2002-03-04 01:43:41,777 ERROR [org.jboss.invocation.jrmp.server.JRMPInvoker] operation failed

                  To get the detail about the error, I get:

                  2002-03-04 01:43:41,762 ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackException, causedBy:
                  java.lang.IllegalStateException: A CMR field cannot be set or added to a relationship in ejbCreate; this should be done in the ejbP$
                  at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.addRelation(JDBCCMRFieldBridge.java:749)
                  at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:146)
                  at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:296)
                  at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:189)
                  at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:108)
                  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:127)
                  at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:166)
                  at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:475)
                  at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.invokeAddRelation(JDBCCMRFieldBridge.java:682)
                  at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.createRelationLinks(JDBCCMRFieldBridge.java:609)
                  at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.setInstanceValue(JDBCCMRFieldBridge.java:573)
                  at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge.setValue(JDBCCMRFieldBridge.java:511)
                  at org.jboss.ejb.plugins.cmp.bridge.EntityBridgeInvocationHandler.invoke(EntityBridgeInvocationHandler.java:115)
                  at org.jboss.proxy.compiler.ProxyCompiler$Runtime.invoke(ProxyCompiler.java:89)
                  at esb.ejb.BusinessUnitCMP$Proxy.setCommunication(Unknown Source)

                  • 6. Re: got IllegalStateException in a place that maybe valid
                    Dain Sundstrom Master

                    I think I have fixed this, but I haven't been able to reproduce the bug. Try the cvs version.

                    In the future, pleas post a bug report at sourceforge along with a small test case.