6 Replies Latest reply on Nov 13, 2003 5:40 PM by Leung Kam Lung

    Primary key Problem

    vincentchun Newbie

      I am using jboss-3.2.2RC4, MySQL 4.

      I use CMP with auto-increment. The type of primary key is java.lang.Integer

      My jbosscmp-jdbc.xml as follow:
      <jbosscmp-jdbc>

      java:/MYDS
      <datasource-mapping>mySQL</datasource-mapping>
      <create-table>true</create-table>
      <remove-table>true</remove-table>


      <enterprise-beans>


      <ejb-name>XXX</ejb-name>
      <table-name>xxx</table-name>

      <cmp-field>
      <field-name>ID</field-name>
      <column-name>ID</column-name>
      <auto-increment/>
      </cmp-field>

      <cmp-field>
      <field-name>AAA</field-name>
      <column-name>aaa</column-name>
      </cmp-field>
      <unknown-pk>
      <unknown-pk-class>java.lang.Integer</unknown-pk-class>
      <field-name>ID</field-name>
      <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"/>


      </enterprise-beans>

      </jbosscmp-jdbc>

      In my ejb-jar.xml file

      ......
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.Integer</prim-key-class>
      False
      <cmp-version>2.x</cmp-version>
      ......

      When I call a create method,
      CMPBean a = home.create(some params);

      the following out println in the screen:
      18:32:16,810 ERROR [STDERR] javax.ejb.CreateException: Primary key for created instance is null.
      18:32:16,820 ERROR [STDERR] at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.createEntity(JDBCStoreManager.java:577)
      18:32:16,820 ERROR [STDERR] at org.jboss.ejb.plugins.CMPPersistenceManager.createEntity(CMPPersistenceManager.java:208)
      18:32:16,820 ERROR [STDERR] at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.createEntity(CachedConnectionInterceptor.java:269)
      18:32:16,820 ERROR [STDERR] at org.jboss.ejb.EntityContainer.createHome(EntityContainer.java:736)
      18:32:16,820 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      18:32:16,820 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      18:32:16,820 ERROR [STDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      18:32:16,820 ERROR [STDERR] at java.lang.reflect.Method.invoke(Method.java:324)
      18:32:16,820 ERROR [STDERR] at org.jboss.ejb.EntityContainer$ContainerInterceptor.invokeHome(EntityContainer.java:1042)
      18:32:16,830 ERROR [STDERR] at org.jboss.ejb.plugins.AbstractInterceptor.invokeHome(AbstractInterceptor.java:88)
      18:32:16,830 ERROR [STDERR] at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invokeHome(EntitySynchronizationInterceptor.java:185)
      18:32:16,830 ERROR [STDERR] at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invokeHome(CachedConnectionInterceptor.java:214)
      18:32:16,830 ERROR [STDERR] at org.jboss.ejb.plugins.AbstractInterceptor.invokeHome(AbstractInterceptor.java:88)
      18:32:16,830 ERROR [STDERR] at org.jboss.ejb.plugins.EntityInstanceInterceptor.invokeHome(EntityInstanceInterceptor.java:91)
      18:32:16,840 ERROR [STDERR] at org.jboss.ejb.plugins.EntityLockInterceptor.invokeHome(EntityLockInterceptor.java:61)
      18:32:16,840 ERROR [STDERR] at org.jboss.ejb.plugins.EntityCreationInterceptor.invokeHome(EntityCreationInterceptor.java:28)
      18:32:16,840 ERROR [STDERR] at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:88)
      18:32:16,840 ERROR [STDERR] at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:267)
      18:32:16,840 ERROR [STDERR] at org.jboss.ejb.plugins.TxInterceptorCMT.invokeHome(TxInterceptorCMT.java:98)
      18:32:16,850 ERROR [STDERR] at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:92)
      18:32:16,850 ERROR [STDERR] at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:120)
      18:32:16,850 ERROR [STDERR] at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:93)
      18:32:16,850 ERROR [STDERR] at org.jboss.ejb.EntityContainer.internalInvokeHome(EntityContainer.java:484)
      18:32:16,850 ERROR [STDERR] at org.jboss.ejb.Container.invoke(Container.java:720)
      18:32:16,850 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      18:32:16,860 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      18:32:16,860 ERROR [STDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      18:32:16,860 ERROR [STDERR] at java.lang.reflect.Method.invoke(Method.java:324)
      18:32:16,860 ERROR [STDERR] at org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284)
      18:32:16,860 ERROR [STDERR] at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
      18:32:16,870 ERROR [STDERR] at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:101)
      18:32:16,870 ERROR [STDERR] at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:90)
      18:32:16,870 ERROR [STDERR] at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
      18:32:16,870 ERROR [STDERR] at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45)
      18:32:16,870 ERROR [STDERR] at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:173)
      18:32:16,880 ERROR [STDERR] at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
      18:32:16,880 ERROR [STDERR] at $Proxy146.create(Unknown Source)
      18:32:16,880 ERROR [STDERR] at fyp.gateway.servlet.TestServlet.doGet(TestServlet.java:68)
      18:32:16,880 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
      18:32:16,880 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
      18:32:16,880 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
      18:32:16,880 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      18:32:16,880 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
      18:32:16,880 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      18:32:16,880 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      18:32:16,890 ERROR [STDERR] at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      18:32:16,890 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      18:32:16,890 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      18:32:16,890 ERROR [STDERR] at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:228)
      18:32:16,890 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      18:32:16,900 ERROR [STDERR] at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
      18:32:16,900 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      18:32:16,900 ERROR [STDERR] at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
      18:32:16,900 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      18:32:16,900 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      18:32:16,900 ERROR [STDERR] at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      18:32:16,900 ERROR [STDERR] at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2416)
      18:32:16,910 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
      18:32:16,910 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      18:32:16,910 ERROR [STDERR] at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
      18:32:16,910 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      18:32:16,910 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
      18:32:16,920 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      18:32:16,920 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
      18:32:16,920 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      18:32:16,920 ERROR [STDERR] at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
      18:32:16,920 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      18:32:16,930 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      18:32:16,930 ERROR [STDERR] at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      18:32:16,930 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
      18:32:16,930 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      18:32:16,930 ERROR [STDERR] at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      18:32:16,930 ERROR [STDERR] at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      18:32:16,940 ERROR [STDERR] at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
      18:32:16,940 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:601)
      18:32:16,940 ERROR [STDERR] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:392)
      18:32:16,940 ERROR [STDERR] at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
      18:32:16,940 ERROR [STDERR] at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619)
      18:32:16,950 ERROR [STDERR] at java.lang.Thread.run(Thread.java:536)

      Although it say "Primary key for created instance is null", I find that I have add one record successfully when I check the MySQL DB.

      Is this a JBoss Bug?

      Anyone can help me to solve this "Primary key for created instance is null" problem?

      Thanks a lot !

        • 1. Re: Primary key Problem
          Paul Kuit Newbie

          Hi,

          I also struggled little time with auto-increment keys,
          xdoclet and jboss. it's simpler then it looks...

          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 to your class tags;

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

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

          But read further!

          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 Microsoft's JDBC driver isn't Type 3 compliant something...


          Okay here my complete code...




          import javax.ejb.CreateException;
          import javax.ejb.EntityBean;
          import javax.ejb.EntityContext;

          import ClientsValue;

          /**
          * @ejb.bean
          * name="Clients"
          * type="CMP"
          * view-type="local"
          * schema="Clients"
          * cmp-version = "2.x"
          * primkey-field = "id"
          * transaction-type = "Container"
          *
          * @ejb.value-object
          * name="Clients"
          * match="*"
          *
          * @ejb.transaction
          * type="Required"
          *
          * @ejb.persistence
          * table-name="Clients"
          *
          * @jboss.persistence
          * create-table="true"
          * remove-table="true"
          *
          * @jboss.entity-command
          * name="mssql-get-generated-keys"
          */

          public abstract class ClientsEJB implements EntityBean {


          /**
          * @ejb.pk-field
          *
          * @ejb.persistent-field
          *
          * @ejb.interface-method
          *
          * @ejb.persistence
          * column-name="clientID"
          *
          * @ejb.transaction
          * type="NotSupported"
          */
          public abstract java.lang.Integer getId();
          public abstract void setId(java.lang.Integer id);

          /**
          * @ejb.persistence
          * column-name="name"
          * @ejb.transaction
          * type="Supports"
          */
          public abstract java.lang.String getName();
          public abstract void setName(java.lang.String name);


          /**
          * @ejb.interface-method
          * @ejb.transaction
          * type="Supports"
          */
          public abstract ClientsValue getClientsValue( );

          /**
          * @ejb.interface-method
          */
          public abstract void setClientsValue( ClientsValue data );


          //==========================================
          // EJB callbacks
          //==========================================

          /**
          * @ejb.create-method
          */
          public Object ejbCreate( ClientsValue data )
          throws CreateException{
          setClientsValue( data );
          return null;
          }

          public void ejbPostCreate( )
          throws CreateException {}

          }



          and added to standardjbosscmp-jdbc.xml (3.2.1);

          <entity-command name="mssql-get-generated-keys"
          class="org.jboss.ejb.plugins.cmp.jdbc.mssql.JDBCMsSQLCreateCommand"/>

          • 2. Re: Primary key Problem
            vincentchun Newbie

            Thanks for your help!

            I found that I have wrong setting in JBoss!

            Now, I have solve my problem!


            You say
            "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 Microsoft's JDBC driver isn't Type 3 compliant something..."

            I see the source of JBoss 3.2.2 (RC4), JBoss doesn't not have org.jboss.ejb.plugins.cmp.jdbc.jdbc3.JDBCGetGeneratedKeysCreateCommand class. You can use the other class to instead it. Those classes are in the standardjbosscmp-jdbc.xml.

            • 3. Re: Primary key Problem
              schristinson Newbie

              Hi,

              I am also using CMP2.0 with a MySQL datasource and am
              using an Integer as the primary key field and auto_increment to generate the key.

              The problem I have is not with the creation of a new
              row, but the subsequent retrieval of the (newly created)
              primary key:

              MyBean b = home.create(a, b, c);
              b.getId();

              In this situation the Id field id the pk, but the above
              code causes a ClassCastException from the JBoss generated
              implementation of the getId() method.

              I can call other getXXX() methods and they work OK.

              Can you tell me what's going on here?

              Thanks.

              • 4. Re: Primary key Problem
                Prabhakar Krishnaswami Newbie

                I have been struggling with not being create an EJB which supports unknown-pk. I am using a firebird driver to access Interbase database in JBoss 320 env.I have tried different configurations but after extensive research settled on the following configuration- a snippet from jbosscmp-jdbc.xml:


                <ejb-name>AddressBean</ejb-name>
                <table-name>AddressBean</table-name>
                <cmp-field>
                <field-name>postalcode</field-name>
                <column-name>CODE</column-name>
                </cmp-field>
                <cmp-field>
                <field-name>street2</field-name>
                <column-name>STREET2</column-name>
                </cmp-field>
                <cmp-field>
                <field-name>street1</field-name>
                <column-name>STREET1</column-name>
                </cmp-field>
                <cmp-field>
                <field-name>region</field-name>
                <column-name>REGION</column-name>
                </cmp-field>
                <cmp-field>
                <field-name>city</field-name>
                <column-name>CITY</column-name>
                </cmp-field>
                <cmp-field>
                <field-name>country</field-name>
                <column-name>COUNTRY</column-name>
                </cmp-field>

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


                The entity command get-generated-keys maps to the following class in standardjbosscmp-jdbc.xml:

                <entity-command name="get-generated-keys" class="org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCKeyGeneratorCreateCommand"/>

                This key generator class is part of jboss.jar. The default section in standardjbosscmp.xml still has an entry:

                <entity-command name="default"/>

                (I didn't want change to get-generated-keys since I have another EJB were the PK is passed in as a parameter in the create method. )

                When the EJB in question is being created, I get an exception the first line reads as follows:


                12:14:20,767 ERROR [AddressBean] Could not create entity
                org.firebirdsql.jdbc.FBSQLException: GDS Exception. validation error for column
                ADDRESSBEAN_UPK, value "*** null ***"

                If I look further down the stack trace, I see

                org.jboss.ejb.plugins.cmp.jdbc.JDBCAbstractCreateCommand.executeInsert.

                Evidently, the key generator class I wanted is not being used. So how would I overcome this problem one EJB requires an id to be passed in during create() while the other relies on automatic creation of keys?

                Any help will greatly be appreciated.


                • 5. Re: Primary key Problem
                  Benjamin Walstrum Newbie

                  The problem is that mysql-get-generated-keys always returns a Long, not an Integer. I have not found a way to configure the datatype of that method (though I'm sure that if you'd like to roll your own you can have fun with that!). However, the problem can be easily solved by having your field be a java.lang.Long. No more ClassCastException.

                  Cheers,

                  Ben Walstrum

                  • 6. Re: Primary key Problem
                    Leung Kam Lung Newbie

                    Hi All,

                    The primary key that I need must be a java.lang.String. Does anyone had try to use the following?

                    <jbosscmp-jdbc>

                    java:/MYDS
                    <datasource-mapping>mySQL</datasource-mapping>
                    <create-table>true</create-table>
                    <remove-table>true</remove-table>


                    <enterprise-beans>


                    <ejb-name>myBean</ejb-name>
                    <table-name>someTable</table-name>

                    <cmp-field>
                    <field-name>PrimaryKey</field-name>
                    <column-name>PrimaryKeyCol</column-name>
                    <auto-increment/>
                    </cmp-field>

                    <cmp-field>
                    <field-name>userName</field-name>
                    <column-name>columnName</column-name>
                    </cmp-field>

                    <unknown-pk>
                    <unknown-pk-class>java.lang.String</unknown-pk-class>
                    <field-name>PrimaryKey</field-name>
                    <column-name>PrimaryKeyCol</column-name>
                    <jdbc-type>VARCHAR</jdbc-type>
                    <sql-type>VARCHAR(255,0)</sql-type>
                    <auto-increment/>
                    </unknown-pk>
                    <entity-command name="mysql-get-generated-keys"
                    class="org.jboss.ejb.plugins.cmp.jdbc.mysql.JDBCMySQLCreateCommand"/>


                    </enterprise-beans>

                    </jbosscmp-jdbc>

                    Thank in advance,
                    Kam