0 Replies Latest reply on Apr 27, 2005 10:19 AM by kharesam

    Problem in automatic primary key generation for Beans having

    kharesam Newbie

      Hi,
      This is regarding the automatic primary key generation of primary keys for entity beans that have
      relationship with another entity bean in JBoss.


      Problem Statement::
      -------------------
      We are using JBoss 4.0.1SP1 for our application. In this application we have two
      EntityBeans, TestUser and TestFT. There is a Unidirectional, many to one relationship
      from TestFT to TestUser. Both these beans have auto-generated primary keys (We are
      using Sybase database). Now when we try to create an instance of TestFT, we get the
      following Exception:


      javax.ejb.CreateException: Primary key for created instance is null.
      at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.createEntity(JDBCStoreManager.java:574)
      at org.jboss.ejb.plugins.CMPPersistenceManager.createEntity(CMPPersistenceManager.java:222)
      at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.createEntity(CachedConnectionInterceptor.java:266)
      at org.jboss.ejb.EntityContainer.createHome(EntityContainer.java:766)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:324)
      at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
      at org.jboss.ejb.EntityContainer$ContainerInterceptor.invokeHome(EntityContainer.java:1113)
      at org.jboss.ejb.plugins.AbstractInterceptor.invokeHome(AbstractInterceptor.java:90)
      at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invokeHome(EntitySynchronizationInterceptor.java:192)
      at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invokeHome(CachedConnectionInterceptor.java:212)
      at org.jboss.ejb.plugins.AbstractInterceptor.invokeHome(AbstractInterceptor.java:90)
      at org.jboss.ejb.plugins.EntityInstanceInterceptor.invokeHome(EntityInstanceInterceptor.java:117)
      at org.jboss.ejb.plugins.EntityLockInterceptor.invokeHome(EntityLockInterceptor.java:61)
      at org.jboss.ejb.plugins.EntityCreationInterceptor.invokeHome(EntityCreationInterceptor.java:28)
      at org.jboss.ejb.plugins.CallValidationInterceptor.invokeHome(CallValidationInterceptor.java:41)
      at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:109)
      at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:313)
      at org.jboss.ejb.plugins.TxInterceptorCMT.invokeHome(TxInterceptorCMT.java:126)
      at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:99)
      at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:121)
      at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:93)
      at org.jboss.ejb.EntityContainer.internalInvokeHome(EntityContainer.java:508)
      at org.jboss.ejb.Container.invoke(Container.java:891)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:324)
      at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:144)
      at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
      at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
      at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:249)
      at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:642)
      at org.jboss.invocation.jrmp.server.JRMPInvoker$MBeanServerAction.invoke(JRMPInvoker.java:805)
      at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:406)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:324)
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
      at sun.rmi.transport.Transport$1.run(Transport.java:148)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
      at java.lang.Thread.run(Thread.java:534)
      at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
      at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
      at sun.rmi.server.UnicastRef.invoke(Unknown Source)
      at org.jboss.invocation.jrmp.server.JRMPInvoker_Stub.invoke(Unknown Source)
      at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke(JRMPInvokerProxy.java:118)
      at org.jboss.invocation.InvokerInterceptor.invokeInvoker(InvokerInterceptor.java:163)
      at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:103)
      at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
      at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:55)
      at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:169)
      at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:91)
      at $Proxy2.create(Unknown Source)
      at test.TestClient.main(Unknown Source)



      Tables corresponding to the above two beans are :

      TestFT: TransactionData(transactionId INTEGER IDENTITY PRIMARY KEY,
      userId INTEGER,
      UpdateTimestamp TIMESTAMP)
      TestUser: UserData ( userId INTEGER IDENTITY PRIMARY KEY,
      fullName VARCHAR(60),
      accountStatus VARCHAR (30) not null,
      statuschangeddate datetime default getdate() not null)



      The userId in TestFT refers to the userId of TestUser.

      NOTE:- We have successfully tested the primary key generation feature for Sybase on JBoss for beans that
      dont have any CMR mappings. It's only when we use CMR that this problem occurs.

      The Deployment Descriptors are given below:
      #########################################################################################################################
      Ejb-jar.xml
      =========================================================================================================================
      <?xml version="1.0" encoding="UTF-8"?>

      <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">

      <ejb-jar >

      <![CDATA[No Description.]]>
      <display-name>Generated by XDoclet</display-name>

      <enterprise-beans>

      <!-- Entity Beans -->

      <![CDATA[]]>
      <display-name>TestFT</display-name>

      <ejb-name>TestFT</ejb-name>

      com.ilts.abs.ejb.entity.TestFTHome
      com.ilts.abs.ejb.entity.TestFT

      <ejb-class>com.ilts.abs.ejb.entity.TestFTCMP</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>TestFT</abstract-schema-name>
      <cmp-field >
      <![CDATA[]]>
      <field-name>transactionId</field-name>
      </cmp-field>
      <cmp-field >
      <![CDATA[]]>
      <field-name>updateTimestamp</field-name>
      </cmp-field>
      <primkey-field>transactionId</primkey-field>

      <!-- Write a file named ejb-finders-TestFTBean.xml if you want to define extra finders. -->



      <![CDATA[]]>
      <display-name>TestUser</display-name>

      <ejb-name>TestUser</ejb-name>

      com.ilts.abs.ejb.entity.TestUserHome
      com.ilts.abs.ejb.entity.TestUser

      <ejb-class>com.ilts.abs.ejb.entity.TestUserCMP</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>TestUser</abstract-schema-name>
      <cmp-field >
      <![CDATA[]]>
      <field-name>userId</field-name>
      </cmp-field>
      <cmp-field >
      <![CDATA[]]>
      <field-name>fullName</field-name>
      </cmp-field>
      <cmp-field >
      <![CDATA[]]>
      <field-name>accountStatus</field-name>
      </cmp-field>
      <cmp-field >
      <![CDATA[]]>
      <field-name>statusChangedDate</field-name>
      </cmp-field>
      <primkey-field>userId</primkey-field>

      <!-- Write a file named ejb-finders-TestUserBean.xml if you want to define extra finders. -->



      <!--
      To add entity beans that you have deployment descriptor info for, add
      a file to your XDoclet merge directory called entity-beans.xml that contains
      the markup for those beans.
      -->

      <!-- Message Driven Beans -->
      <!--
      To add message driven beans that you have deployment descriptor info for, add
      a file to your XDoclet merge directory called message-driven-beans.xml that contains
      the <message-driven></message-driven> markup for those beans.
      -->

      </enterprise-beans>

      <!-- Relationships -->

      <ejb-relation >
      <ejb-relation-name>User-Funds</ejb-relation-name>

      <ejb-relationship-role >
      <ejb-relationship-role-name>FundsTransactions-of-User</ejb-relationship-role-name>
      Many
      <relationship-role-source >
      <ejb-name>TestFT</ejb-name>
      </relationship-role-source>
      <cmr-field >
      <cmr-field-name>user</cmr-field-name>
      </cmr-field>
      </ejb-relationship-role>

      <ejb-relationship-role >
      <ejb-relationship-role-name>User-performs-FundsTransactions</ejb-relationship-role-name>
      One
      <relationship-role-source >
      <ejb-name>TestUser</ejb-name>
      </relationship-role-source>
      </ejb-relationship-role>

      </ejb-relation>
      <!--
      To add relationships for beans not managed by XDoclet, add
      a file to your XDoclet merge directory called relationships.xml that contains
      the <ejb-relation></ejb-relation> markups for those beans.
      -->


      <!-- Assembly Descriptor -->
      <!--
      To specify your own assembly descriptor info here, add a file to your
      XDoclet merge directory called assembly-descriptor.xml that contains
      the <assembly-descriptor></assembly-descriptor> markup.
      -->

      <assembly-descriptor >
      <!--
      To specify additional security-role elements, add a file in the merge
      directory called ejb-security-roles.xml that contains them.
      -->

      <!-- method permissions -->
      <!--
      To specify additional method-permission elements, add a file in the merge
      directory called ejb-method-permissions.ent that contains them.
      -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- finder permissions -->

      <!-- transactions -->
      <!--
      To specify additional container-transaction elements, add a file in the merge
      directory called ejb-container-transaction.ent that contains them.
      -->

      <!-- finder transactions -->

      <!--
      To specify an exclude-list element, add a file in the merge directory
      called ejb-exclude-list.xml that contains it.
      -->
      </assembly-descriptor>

      </ejb-jar>


      #########################################################################################################################
      jboss.xml
      =========================================================================================================================
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd">



      <enterprise-beans>

      <!--
      To add beans that you have deployment descriptor info for, add
      a file to your XDoclet merge directory called jboss-beans.xml that contains
      the , and <message-driven></message-driven>
      markup for those beans.
      -->


      <ejb-name>TestFT</ejb-name>
      <jndi-name>abs.TestFT</jndi-name>
      <configuration-name>INSERT AFTER EJB_POST_CREATE CMP 2.x EntityBean</configuration-name>

      <method-attributes>
      </method-attributes>





      <ejb-name>TestUser</ejb-name>
      <jndi-name>abs.TestUser</jndi-name>

      <method-attributes>
      </method-attributes>




      </enterprise-beans>

      <resource-managers>
      </resource-managers>

      <container-configurations>
      <container-configuration>
      <container-name>BeanOptimisticLocking</container-name>
      <call-logging>false</call-logging>
      <invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name>
      <sync-on-commit-only>false</sync-on-commit-only>
      <insert-after-ejb-post-create>true</insert-after-ejb-post-create>
      <call-ejb-store-on-clean>true</call-ejb-store-on-clean>
      <container-interceptors>
      org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor
      org.jboss.ejb.plugins.LogInterceptor
      org.jboss.ejb.plugins.SecurityInterceptor
      org.jboss.ejb.plugins.TxInterceptorCMT
      org.jboss.ejb.plugins.CallValidationInterceptor
      org.jboss.ejb.plugins.MetricsInterceptor
      org.jboss.ejb.plugins.EntityCreationInterceptor
      org.jboss.ejb.plugins.EntityLockInterceptor
      org.jboss.ejb.plugins.EntityInstanceInterceptor
      org.jboss.ejb.plugins.EntityReentranceInterceptor
      org.jboss.resource.connectionmanager.CachedConnectionInterceptor
      org.jboss.ejb.plugins.EntitySynchronizationInterceptor
      org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor
      </container-interceptors>
      <instance-pool>org.jboss.ejb.plugins.EntityInstancePool</instance-pool>
      <instance-cache>org.jboss.ejb.plugins.InvalidableEntityInstanceCache</instance-cache>
      <persistence-manager>org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager</persistence-manager>
      <locking-policy>org.jboss.ejb.plugins.lock.JDBCOptimisticLock</locking-policy>
      <container-cache-conf>
      <cache-policy>org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicy</cache-policy>
      <cache-policy-conf>
      <min-capacity>50</min-capacity>
      <max-capacity>1000000</max-capacity>
      <overager-period>300</overager-period>
      <max-bean-age>600</max-bean-age>
      <resizer-period>400</resizer-period>
      <max-cache-miss-period>60</max-cache-miss-period>
      <min-cache-miss-period>1</min-cache-miss-period>
      <cache-load-factor>0.75</cache-load-factor>
      </cache-policy-conf>
      </container-cache-conf>
      <container-pool-conf>
      100
      </container-pool-conf>
      <commit-option>B</commit-option>
      </container-configuration>
      <container-configuration>
      <container-name>INSERT AFTER EJB_POST_CREATE CMP 2.x EntityBean</container-name>
      <call-logging>false</call-logging>
      <invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name>
      <sync-on-commit-only>false</sync-on-commit-only>
      <insert-after-ejb-post-create>true</insert-after-ejb-post-create>
      <call-ejb-store-on-clean>true</call-ejb-store-on-clean>
      <container-interceptors>
      org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor
      org.jboss.ejb.plugins.LogInterceptor
      org.jboss.ejb.plugins.SecurityInterceptor
      org.jboss.ejb.plugins.TxInterceptorCMT
      org.jboss.ejb.plugins.CallValidationInterceptor
      org.jboss.ejb.plugins.MetricsInterceptor
      org.jboss.ejb.plugins.EntityCreationInterceptor
      org.jboss.ejb.plugins.EntityLockInterceptor
      org.jboss.ejb.plugins.EntityInstanceInterceptor
      org.jboss.ejb.plugins.EntityReentranceInterceptor
      org.jboss.resource.connectionmanager.CachedConnectionInterceptor
      org.jboss.ejb.plugins.EntitySynchronizationInterceptor
      org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor
      </container-interceptors>
      <instance-pool>org.jboss.ejb.plugins.EntityInstancePool</instance-pool>
      <instance-cache>org.jboss.ejb.plugins.InvalidableEntityInstanceCache</instance-cache>
      <persistence-manager>org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager</persistence-manager>
      <locking-policy>org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock</locking-policy>
      <container-cache-conf>
      <cache-policy>org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicy</cache-policy>
      <cache-policy-conf>
      <min-capacity>50</min-capacity>
      <max-capacity>1000000</max-capacity>
      <overager-period>300</overager-period>
      <max-bean-age>600</max-bean-age>
      <resizer-period>400</resizer-period>
      <max-cache-miss-period>60</max-cache-miss-period>
      <min-cache-miss-period>1</min-cache-miss-period>
      <cache-load-factor>0.75</cache-load-factor>
      </cache-policy-conf>
      </container-cache-conf>
      <container-pool-conf>
      100
      </container-pool-conf>
      <commit-option>B</commit-option>
      </container-configuration>
      </container-configurations>



      #########################################################################################################################
      jbosscmp-jdbc.xml
      =========================================================================================================================
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 4.0//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_4_0.dtd">

      <jbosscmp-jdbc>

      java:/sybaseDataSource
      <datasource-mapping>Sybase</datasource-mapping>
      <preferred-relation-mapping>foreign-key</preferred-relation-mapping>


      <enterprise-beans>

      <!--
      To add beans that you have deployment descriptor info for, add
      a file to your XDoclet merge directory called jbosscmp-jdbc-beans.xml
      that contains the markup for those beans.
      -->


      <ejb-name>TestFT</ejb-name>

      <table-name>TransactionData</table-name>

      <cmp-field>
      <field-name>transactionId</field-name>
      <column-name>transactionId</column-name>

      </cmp-field>
      <cmp-field>
      <field-name>updateTimestamp</field-name>
      <column-name>UpdateTimestamp</column-name>

      </cmp-field>

      <unknown-pk>
      <unknown-pk-class>java.lang.Integer</unknown-pk-class>
      <column-name>transactionId</column-name>
      <jdbc-type>INTEGER</jdbc-type>
      <sql-type>INTEGER</sql-type>
      </unknown-pk>
      <entity-command name="sybase-fetch-key" class="org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCSybaseCreateCommand">
      SELECT @@IDENTITY
      </entity-command>
      <!-- jboss 3.2 features -->
      <!-- optimistic locking does not express the exclusions needed -->





      <ejb-name>TestUser</ejb-name>

      <table-name>UserData</table-name>

      <cmp-field>
      <field-name>userId</field-name>
      <column-name>userId</column-name>

      </cmp-field>
      <cmp-field>
      <field-name>fullName</field-name>
      <column-name>fullName</column-name>

      </cmp-field>
      <cmp-field>
      <field-name>accountStatus</field-name>
      <column-name>accountStatus</column-name>

      </cmp-field>
      <cmp-field>
      <field-name>statusChangedDate</field-name>
      <column-name>StatusChangedDate</column-name>

      </cmp-field>

      <unknown-pk>
      <unknown-pk-class>java.lang.Integer</unknown-pk-class>
      <column-name>userId</column-name>
      <jdbc-type>INTEGER</jdbc-type>
      <sql-type>INTEGER</sql-type>
      </unknown-pk>
      <entity-command name="sybase-fetch-key" class="org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCSybaseCreateCommand">
      SELECT @@IDENTITY
      </entity-command>
      <!-- jboss 3.2 features -->
      <!-- optimistic locking does not express the exclusions needed -->


      </enterprise-beans>


      <ejb-relation>
      <ejb-relation-name>User-Funds</ejb-relation-name>
      <foreign-key-mapping/>

      <ejb-relationship-role>
      <ejb-relationship-role-name>FundsTransactions-of-User</ejb-relationship-role-name>
      <fk-constraint>true</fk-constraint>
      <key-fields/>

      </ejb-relationship-role>
      <ejb-relationship-role>
      <ejb-relationship-role-name>User-performs-FundsTransactions</ejb-relationship-role-name>
      <key-fields>
      <key-field>
      <field-name>userId</field-name>
      <column-name>userId</column-name>
      <jdbc-type>INTEGER</jdbc-type>
      <sql-type>INTEGER</sql-type>
      </key-field>
      </key-fields>

      </ejb-relationship-role>
      </ejb-relation>
      <!--
      To add jboss relationships for beans not managed by XDoclet, add
      a file to your XDoclet merge directory called jbosscmp-jdbc-relationships.xml that contains
      the <ejb-relation></ejb-relation> markups for those beans.
      -->


      </jbosscmp-jdbc>