Problem in automatic primary key generation for Beans having
kharesam Apr 27, 2005 10:26 AMHi,
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>