Auto-increment PK with Hypersonic, can you review my code?
fjanon Jan 10, 2006 10:05 AMI wrote a short example to figure out how to get Hypersonic to generate the primary key automatically. I started from the book "Enterprise Java Beans 4th Ed". Here is the code of the bean, the client and the deployment files. It works but I am not sure that it is the correct way of doing it. Specifically do I need "<pk-constraint>false</pk-constraint>" and "<entity-command name="hsqldb-fetch-key"/>"? Please review and comment. I am running JBoss 4.0.2. I build the example with "ant" then I run the client with "client_61 john mary peter jill mary bob". The Hypersonic log shows:
DROP TABLE CUSTOMER
CREATE TABLE CUSTOMER (ID INTEGER NOT NULL IDENTITY, LAST_NAME VARCHAR(256))
SET AUTOCOMMIT FALSE
INSERT INTO CUSTOMER VALUES(0,'john')
COMMIT
INSERT INTO CUSTOMER VALUES(1,'mary')
COMMIT
INSERT INTO CUSTOMER VALUES(2,'peter')
COMMIT
INSERT INTO CUSTOMER VALUES(3,'jill')
COMMIT
INSERT INTO CUSTOMER VALUES(4,'mary')
COMMIT
INSERT INTO CUSTOMER VALUES(5,'bob')
COMMIT
and the client console:
C:\workbook\ex00>client_61 john mary peter jill mary bob
Buildfile: build.xml
prepare:
compile:
ejbjar:
run.client_61:
[java] Getting initial context
[java] Looking up CustomerHomeRemote
[java] Creating Customers
[java] john
[java] mary
[java] peter
[java] jill
[java] mary
[java] bob
[java] Finding all names
[java] Displaying all names
[java] Customer Id = 0 Name john
[java] Customer Id = 1 Name mary
[java] Customer Id = 2 Name peter
[java] Customer Id = 3 Name jill
[java] Customer Id = 4 Name mary
[java] Customer Id = 5 Name bob
Thanks a lot!
Fred
-------------------------------
ejb-jar.xml <?xml version="1.0"?> <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1"> <enterprise-beans> <entity> <ejb-name>CustomerEJB</ejb-name> <home>com.titan.customer.CustomerHomeRemote</home> <remote>com.titan.customer.CustomerRemote</remote> <ejb-class>com.titan.customer.CustomerBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.Integer</prim-key-class> <reentrant>False</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>Customer</abstract-schema-name> <cmp-field><field-name>id</field-name></cmp-field> <cmp-field><field-name>lastName</field-name></cmp-field> <primkey-field>id</primkey-field> <query> <query-method> <method-name>findAllNames</method-name> <method-params/> </query-method> <ejb-ql> SELECT OBJECT(c) FROM Customer AS c </ejb-ql> </query> </entity> </enterprise-beans> <assembly-descriptor> <security-role> <role-name>Employees</role-name> </security-role> <method-permission> <role-name>Employees</role-name> <method> <ejb-name>CustomerEJB</ejb-name> <method-name>*</method-name> </method> </method-permission> <container-transaction> <method> <ejb-name>CustomerEJB</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> ------------------------------- jbosscmp-jdbc.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 3.2//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_3_2.dtd"> <jbosscmp-jdbc> <defaults> <datasource>java:/DefaultDS</datasource> <datasource-mapping>Hypersonic SQL</datasource-mapping> <create-table>true</create-table> <remove-table>true</remove-table> </defaults> <enterprise-beans> <entity> <ejb-name>CustomerEJB</ejb-name> <pk-constraint>false</pk-constraint> <table-name>Customer</table-name> <cmp-field> <field-name>id</field-name> <column-name>ID</column-name> <auto-increment/> </cmp-field> <cmp-field> <field-name>lastName</field-name> <column-name>LAST_NAME</column-name> </cmp-field> <entity-command name="hsqldb-fetch-key"/> </entity> </enterprise-beans> </jbosscmp-jdbc> ------------------------------- CustomerBean.java package com.titan.customer; import javax.ejb.EntityContext; import javax.ejb.CreateException; public abstract class CustomerBean implements javax.ejb.EntityBean { public Integer ejbCreate(String lastName) throws CreateException { setLastName(lastName); return null; } public void ejbPostCreate(String lastName) { } public abstract Integer getId(); public abstract void setId(Integer id); public abstract String getLastName(); public abstract void setLastName(String lname); // standard callback methods public void setEntityContext(EntityContext ec){} public void unsetEntityContext(){} public void ejbLoad(){} public void ejbStore(){} public void ejbActivate(){} public void ejbPassivate(){} public void ejbRemove(){} } ------------------------------- CustomerHomeRemote.java package com.titan.customer; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.FinderException; import java.util.*; // for Collection public interface CustomerHomeRemote extends javax.ejb.EJBHome { public CustomerRemote create(String lastName) throws CreateException, RemoteException; public CustomerRemote findByPrimaryKey(Integer id) throws FinderException, RemoteException; public Collection findAllNames() throws FinderException, RemoteException; } ------------------------------- CustomerRemote.java package com.titan.customer; import java.rmi.RemoteException; public interface CustomerRemote extends javax.ejb.EJBObject { public Integer getId() throws RemoteException; public String getLastName() throws RemoteException; public void setLastName(String lname) throws RemoteException; } ------------------------------- Client_61.java package com.titan.clients; import com.titan.customer.CustomerHomeRemote; import com.titan.customer.CustomerRemote; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import javax.naming.Context; import javax.naming.NamingException; import java.util.*; // for Collection public class Client_61 { public static void main(String [] args) { try { if (args.length < 1) { System.out.println("Usage: java com.titan.clients.Client_61 <name0> <name1> ..."); System.exit(-1); } System.out.println("Getting initial context"); Context jndiContext = getInitialContext(); System.out.println("Looking up CustomerHomeRemote"); Object obj = jndiContext.lookup("CustomerHomeRemote"); CustomerHomeRemote home = (CustomerHomeRemote) PortableRemoteObject.narrow(obj, CustomerHomeRemote.class); // Create Customers System.out.println("Creating Customers"); for(int i = 0; i < args.length; i++) { String lastName = args; System.out.println(" " + lastName); CustomerRemote customer = home.create(lastName); } // Find and display all Customers System.out.println("Finding all names"); Collection allCustomers = home.findAllNames(); System.out.println("Displaying all names"); Iterator it = allCustomers.iterator(); while (it.hasNext()) { CustomerRemote customer = (CustomerRemote)it.next(); Integer primaryKey = customer.getId(); String lastName = customer.getLastName(); System.out.println("Customer Id = " + primaryKey + " Name " + lastName); } } catch (java.rmi.RemoteException re) { re.printStackTrace(); } catch (Throwable t) { t.printStackTrace(); } } public static Context getInitialContext() throws Exception { return new InitialContext(); } } -------------------------------------------- build.xml <?xml version="1.0"?> <!-- ======================================================================= --> <!-- JBoss build file --> <!-- ======================================================================= --> <project name="JBoss" default="ejbjar" basedir="."> <property environment="env"/> <property name="src.dir" value="${basedir}/src/main"/> <property name="src.resources" value="${basedir}/src/resources"/> <property name="jboss.home" value="${env.JBOSS_HOME}"/> <property name="build.dir" value="${basedir}/build"/> <property name="build.classes.dir" value="${build.dir}/classes"/> <!-- Build classpath --> <path id="classpath"> <fileset dir="${jboss.home}/client"> <include name="**/*.jar"/> </fileset> <pathelement location="${build.classes.dir}"/> <!-- So that we can get jndi.properties for InitialContext --> <pathelement location="${basedir}/jndi"/> </path> <!-- =================================================================== --> <!-- Prepares the build directory --> <!-- =================================================================== --> <target name="prepare" > <mkdir dir="${build.dir}"/> <mkdir dir="${build.classes.dir}"/> </target> <!-- =================================================================== --> <!-- Compiles the source code --> <!-- =================================================================== --> <target name="compile" depends="prepare"> <javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="on" deprecation="on" optimize="off" includes="**"> <classpath refid="classpath"/> </javac> </target> <target name="ejbjar" depends="compile"> <jar jarfile="build/titan.jar"> <fileset dir="${build.classes.dir}"> <include name="com/titan/customer/*.class"/> </fileset> <fileset dir="${src.resources}/"> <include name="**/*.xml"/> </fileset> </jar> <copy file="build/titan.jar" todir="${jboss.home}/server/default/deploy"/> </target> <target name="run.client_61" depends="ejbjar"> <java classname="com.titan.clients.Client_61" fork="yes" dir="."> <classpath refid="classpath"/> <arg line="${param.pk1} ${param.fn1} ${param.ln1} ${param.pk2} ${param.fn2} ${param.ln2}"/> </java> </target> <!-- =================================================================== --> <!-- Cleans up generated stuff --> <!-- =================================================================== --> <target name="clean.db"> <delete dir="${jboss.home}/server/default/data/hypersonic"/> </target> <target name="clean" > <delete dir="${build.dir}"/> <delete file="${jboss.home}/server/default/deploy/titan.jar"/> </target> </project>