1 Reply Latest reply on Jun 22, 2007 12:28 AM by muralidharanr

    Primary key for created instance is null...

    achitre

      Hello,

      I am porting an application from Weblogic to JBoss. I am running into issues while converting the following Weblogic property:

      <delay-database-insert-until>ejbPostCreate</delay-database-insert-until>

      I believe I am following all the steps necessary, but it doesn't seem to work. Here's what I have done:

      1) In JBoss.xml I added the following section:

      <container-configurations>
      
       <container-configuration extends="Standard CMP 2.x EntityBean">
       <container-name>XYZ Custom Configuration</container-name>
       <insert-after-ejb-post-create>true</insert-after-ejb-post-create>
       </container-configuration>
      
      </container-configurations>
      


      2) In JBoss.xml I associated the configuration to the appropriate EJB:

      <entity>
       <ejb-name>RevisionHistoryEJB</ejb-name>
       <configuration-name>XYZ Custom Configuration</configuration-name>
       <local-jndi-name>RevisionHistoryEJB.RevisionHistoryHome</local-jndi-name>
      </entity>
      


      3) Added <auto-increment/> tag to the ejb in jbosscmp-jdbc.xml.

      <entity>
       <ejb-name>RevisionHistoryEJB</ejb-name>
       <create-table>false</create-table>
       <table-name>RevisionHistory</table-name>
       <cmp-field>
       <field-name>id</field-name>
       <column-name>id</column-name>
       <auto-increment/>
       </cmp-field>
       <cmp-field>
       <field-name>user</field-name>
       <column-name>user_</column-name>
       </cmp-field>
       <cmp-field>
       <field-name>scenarioId</field-name>
       <column-name>scenarioId</column-name>
       </cmp-field>
       <entity-command name="oracle-sequence" class="org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCOracleCreateCommand">
       <attribute name="sequence">revisionHistory_seq</attribute>
       </entity-command>
      
      
       </entity>
      


      This doesn't seem to work. Am I missing something?

      Some more info... I debugged thru the JBoss 4.0 code. Here's what I think is going on:

      1) JDBCStoreManager.java has the following code:

      public Object createEntity(Method createMethod, Object[] args, EntityEnterpriseContext ctx)
       throws CreateException
       {
       Object pk = createEntityCommand.execute(createMethod, args, ctx);
       if(pk == null)
       throw new CreateException("Primary key for created instance is null.");
       return pk;
       }
      



      2) The above method calls the following execute method in JDBCAbstractCreateCommand.java

      public Object execute(Method m, Object[] args, EntityEnterpriseContext ctx) throws CreateException
       {
       // TODO: implement this logic nicer
       if(insertAfterEjbPostCreate)
       {
       if(!JDBCEntityBridge.isEjbCreateDone(ctx))
       {
       checkCreateAllowed();
       generateFields(ctx);
       JDBCEntityBridge.setEjbCreateDone(ctx);
       }
       else
       {
       beforeInsert(ctx);
       performInsert(ctx);
       afterInsert(ctx);
       JDBCEntityBridge.setCreated(ctx);
       }
       }
       else
       {
       checkCreateAllowed();
       generateFields(ctx);
       beforeInsert(ctx);
       performInsert(ctx);
       afterInsert(ctx);
       JDBCEntityBridge.setCreated(ctx);
       }
       return getPrimaryKey(ctx);
       }
      


      When we get here, the 'insertAfterEjbPostCreate' is set to 'true' (which is good!), but 'isEjbCreateDone' is set to FALSE. So when we get back from this method the 'primary key' will always be null - because we didn't insert a row in the database. As a result, we will always get the 'Primary key for created instance is null' exception from the 'createEntity' method of JDBCStoreManager.

      Am I missing something?


      One last note, this problem goes away when all the CMR fields are declared as NULL on the database, but I think that's just a workaround; not the real solution.

      If anyone knows the real solution, please let me know. Thanks.