3 Replies Latest reply on Sep 30, 2003 12:33 PM by paulkuit

    JBoss 3.2.1 MySQL auto-inc failure

    landrus

      Hi.

      I have the following problem. I have an entity bean, with an auto-incremented index. Whenever I create a new Bean, the corresponding values are stored inside the database and the index is created correctly. But jboss generates the following Exception

      javax.ejb.EJBException: Internal error setting instance field id; CausedByException is: null

      java.lang.IllegalArgumentException
      at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)

      I have now idea, what my problem is, since the database entry is correct. Here is my jbosscmp-jdbc.xml:


      <ejb-name>User</ejb-name>
      java:/MySqlDS
      <datasource-mapping>mySQL</datasource-mapping>
      <create-table>true</create-table>
      <remove-table>true</remove-table>
      <table-name>user</table-name>

      <cmp-field>
      <field-name>id</field-name>
      <jdbc-type>INTEGER</jdbc-type>
      <sql-type>INTEGER</sql-type>
      <auto-increment/>
      </cmp-field>
      <cmp-field>
      <field-name>name</field-name>
      </cmp-field>
      <cmp-field>
      <field-name>password</field-name>
      </cmp-field>
      <unknown-pk>
      <unknown-pk-class>java.lang.Integer</unknown-pk-class>
      <column-name>id</column-name>
      <jdbc-type>INTEGER</jdbc-type>
      <sql-type>INTEGER</sql-type>
      <auto-increment/>
      </unknown-pk>
      <entity-command name="mysql-get-generated-keys">
      </entity-command>


      Ciao, Landrus

        • 1. Re: JBoss 3.2.1 MySQL auto-inc failure
          sverker

          A message a bit down in the thread found at http://www.jboss.org/modules/bb/index.html?module=bb&op=viewtopic&t= gives detailed information about how to do it.

          In summary, in addition to the auto-increment tag you also have to give an entity-command tag with name="mysql-get-generated-keys"

          • 2. Re: JBoss 3.2.1 MySQL auto-inc failure
            sundaram

            Hi,



            you need to added the following methods code in your UserImpl.java

            /**
            * This is to get the unknown primary key. We just get the primary key
            * from the entity context and cast it to the "known" class.
            *
            * @ejb.interface-method
            * view-type="both"
            */
            public Integer getGeneratedPrimaryKey() {
            return (Integer) entityContext.getPrimaryKey();
            }


            you can use the BaseEntityBean.java code from the xdoclet sample.

            import javax.ejb.*;

            /**
            * SuperClass for all entity beans, implementing common entity bean methods.
            *
            * @author youremail@yourdomain.com
            * @version $Revision: 1.6 $
            */
            public abstract class BaseEntityBean {
            /** Reference to EntityContext. */
            protected EntityContext entityContext = null;

            /**
            * The creation-date of the entity. This field is purely to track when
            * this entity was created, and should be set in ejbCreate
            * (setCreationDate(new Date());.
            * It is not included in the value object.
            *
            * We use the qualified name here because XDoclet doesn't copy imports from
            * base classes into the generated interfaces.
            *
            * @ejb.persistence column-name="creationDate"
            * @ejb.interface-method
            *
            * @ejb.value-object exclude="true" match="*"
            *
            */
            public abstract java.util.Date getCreationDate();

            /** @ejb.interface-method */
            public abstract void setCreationDate(java.util.Date creationDate);

            /**
            * Gets the EntityContext. To be used by classes extending this.
            * @return the EntityContext of the EJB
            */
            protected EntityContext getEntityContext() {
            return entityContext;
            }

            /** Required to implement EntityBean. Sets the EntityContext. */
            public void setEntityContext(EntityContext entityContext) throws EJBException {
            this.entityContext = entityContext;
            }

            /** Required to implement EntityBean. Sets the EntityContext to null. */
            public void unsetEntityContext() throws EJBException {
            entityContext = null;
            }

            /** Required to implement EntityBean. Not implemented. */
            public void ejbActivate() throws EJBException { }

            /** Required to implement EntityBean. Not implemented. */
            public void ejbPassivate() throws EJBException { }

            /** Required to implement EntityBean. Not implemented. */
            public void ejbLoad() throws EJBException { }

            /** Required to implement EntityBean. Not implemented. */
            public void ejbStore() throws EJBException { }

            /** Required to implement EntityBean. Not implemented. */
            public void ejbRemove() throws RemoveException, EJBException { }
            }


            then change you class like this

            public abstract class UserImpl extenextends BaseEntityBean implements EntityBean {

            also add the
            public Integer getGeneratedPrimaryKey() method


            look at the xdoclet AccountBean.java program

            -SR

            • 3. Re: JBoss 3.2.1 MySQL auto-inc failure
              paulkuit

              I didn't need any auto-increment tag or unknown-pk stuff; only entity-command

              Only 1 thing you need to tell XDoclet! All the rest is really the same as normal... except that you don't setId(new UID()) in ejbCreate... of cource.

              Only add this to your class tags

              * @jboss.entity-command
              * name="mssql-get-generated-keys"

              So don't need any unknown-pk stuff at all...

              I read this in other postings already, but they didn't tell me these (get-generated-keys) entity-commands are mapped to CreateCommand classes, defined in standardjbosscmp-jdbc.xml.

              Depending on jboss version (3.2.1 doesn't have this mapping stated above, for mssql), you need to define a mapping yourself;

              1. See package org.jboss.ejb.plugins.cmp.jdbc in jboss.jar for database vendor specific CreateCommand classes)

              2. Define in standardjbosscmp-jdbc.xml, or in xdoclet using
              @jboss.entity-command
              * name="get-generated-keys"
              * class="org.jboss.ejb.plugins.cmp.jdbc.mssql.JDBCMsSQLCreateCommand"

              Obs.
              - the package with CreateCommands classes changed in 3.2.2 (RC4), RC4 gave me transaction problems anyway...
              - the default org.jboss.ejb.plugins.cmp.jdbc.jdbc3.JDBCGetGeneratedKeysCreateCommand didn't work for me... Maybe MSSQL driver isn't Type 3 compliant something...