EJB3: Mapping Persistent Objects Example 2

by admin ~ October 21, 2008

Following are the example from the chapter “Mapping Persistent Objects” from the book “Enterprise JavaBeans 3.0″ by Bill Bruke & Richard Monson-Haefel. This example I have tried it out on JBoss AS 5.0.0.CR1. I have used Postgresql as the database. And I have used eclipse WTP as IDE.


Example 2: @IdClass

This example shows the use of @javax.persistence.IdClass to map a primary key class to the database.


Client.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.titan.clients;
 
import com.titan.travelagent.TravelAgentRemote;
import com.titan.domain.*;
import javax.naming.Context;
 
public class Client {
	public static void main(String[] args) {
		try {
			Context jndiContext = getInitialContext();
			Object ref = jndiContext.lookup("TitanCruises/TravelAgentBean/remote");
			TravelAgentRemote dao = (TravelAgentRemote) ref;
 
			Customer cust = new Customer();
			cust.setFirstName("Bill");
			cust.setLastName("Burke");
			cust.setSsn(9999999);
 
			dao.createCustomer(cust);
 
			cust = dao.findCustomer("Burke", 9999999);
			System.out.println(cust.getFirstName());
			System.out.println(cust.getLastName());
			System.out.println(cust.getSsn());
		} catch (javax.naming.NamingException ne) {
			ne.printStackTrace();
		}
	}
 
	public static Context getInitialContext()
			throws javax.naming.NamingException {
		return new javax.naming.InitialContext();
	}
}

jndi.properties

1
2
3
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=127.0.0.1:1099

TravelAgentRemote.java

1
2
3
4
5
6
7
8
9
10
11
package com.titan.travelagent;
 
import javax.ejb.Remote;
 
import com.titan.domain.Customer;
 
@Remote
public interface TravelAgentRemote {
   public void createCustomer(Customer cust);
   public Customer findCustomer(String lastName, long ssn);
}

TravelAgentBean.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.titan.travelagent;
 
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.titan.domain.Customer; 
import com.titan.domain.CustomerPK;
 
@Stateless
public class TravelAgentBean implements TravelAgentRemote {
    @PersistenceContext(unitName="titan") private EntityManager manager;
 
    public void createCustomer(Customer cust){
		manager.persist(cust);
    }
 
   public Customer findCustomer(String lastName, long ssn){
      CustomerPK pk = new CustomerPK(lastName, ssn);
      return manager.find(Customer.class, pk);
   }
}

Customer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.titan.domain;
 
import javax.persistence.*;
 
@Entity
@IdClass(CustomerPK.class)
public class Customer implements java.io.Serializable {
   private String firstName;
   private String lastName;
   private long ssn;
 
   public String getFirstName() { return firstName; }
   public void setFirstName(String firstName) { this.firstName = firstName; }
 
   @Id
   public String getLastName() { return lastName; }
   public void setLastName(String lastName) { this.lastName = lastName; }
 
 
 
   @Id
   public long getSsn() { return ssn; }
   public void setSsn(long ssn) { this.ssn = ssn; }
}

CustomerPK.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.titan.domain;
 
public class CustomerPK implements java.io.Serializable {
   private String lastName;
   private long ssn;
 
   public CustomerPK() {}
 
   public CustomerPK(String lastName, long ssn) {
      this.lastName = lastName;
      this.ssn = ssn;
   }
 
   public String getLastName() { return this.lastName; }
   public void setLastName(String lastName) { this.lastName = lastName; }
 
   public long getSsn() { return ssn; }
   public void setSsn(long ssn) { this.ssn = ssn; }
 
   public boolean equals(Object obj) {
      if (obj == this) return true;
      if (!(obj instanceof CustomerPK)) return false;
      CustomerPK pk = (CustomerPK)obj;
      if (!lastName.equals(pk.lastName)) return false;
      if (ssn != pk.ssn) return false;
      return true;
   }
 
   public int hashCode() {
      return lastName.hashCode() + (int)ssn;
   }
}

persistence.xml

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<persistence:persistence version="1.0" xmlns:persistence="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd ">
  <persistence:persistence-unit name="titan" transaction-type="JTA">
    <persistence:description>Chapter: 6</persistence:description>
    <persistence:jta-data-source>java:/TitanDB</persistence:jta-data-source>
    <persistence:properties>
    	<persistence:property name="hibernate.hbm2ddl.auto" value="create"/>
    </persistence:properties>
  </persistence:persistence-unit>
</persistence:persistence>

application.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC
	"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
	"http://java.sun.com/dtd/application_1_3.dtd">
<application>
	<display-name>TitanCruisesExample</display-name>
	<module>
		<ejb>TravelAgentBean.jar</ejb>
	</module>
	<module>
		<ejb>Customer.jar</ejb>
	</module>
</application>

Building the application: build.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="UTF-8"?>
<project name="Packaging Generator" default="_packaging_generation_">
	<target name="_packaging_generation_" depends="TitanCruisesExample" />
	<target name="TitanCruisesExample" description="TitanCruises.ear" depends="TravelAgentBean">
		<jar destfile="TitanCruises.ear">
			<zipfileset dir="conf" prefix="META-INF">
				<include name="application.xml" />
			</zipfileset>
			<zipfileset dir="/home/ranjan/workspaceEJB3/TitanCruises6_2">
				<include name="TravelAgentBean.jar" />
				<include name="Customer.jar" />
			</zipfileset>
		</jar>
	</target>
	<target name="TravelAgentBean" description="TravelAgentBean.jar" depends="Customer">
		<jar destfile="TravelAgentBean.jar">
			<zipfileset dir="/home/ranjan/workspaceEJB3/TitanCruises6_2/bin/com/titan/travelagent" prefix="com/titan/travelagent">
				<include name="TravelAgentRemote.class"/>
				<include name="TravelAgentBean.class"/>
			</zipfileset>	
		</jar>
	</target>
	<target name="Customer" description="Customer.jar">
		<jar destfile="Customer.jar">
			<zipfileset dir="conf" prefix="META-INF">
				<include name="persistence.xml" />
			</zipfileset>
			<zipfileset dir="/home/ranjan/workspaceEJB3/TitanCruises6_2/bin/com/titan/domain" prefix="com/titan/domain"/>
		</jar>
	</target>
</project>

Packaging Structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
TitanCruises.ear
  |
  |--- META-INF
  |     |
  |     |--- application.xml
  |     |
  |     |--- MENIFEST.MF
  |
  |--- Customer.jar
  |     |
  |     |--- META-INF 
  |     |     |
  |     |     |--- persistence.xml
  |     |     |    
  |     |     |--- MENIFEST.MF
  |     |
  |     |--- com
  |           |
  |           |--- titan
  |                  |
  |                  |--- domain
  |                         |
  |                         |--- Customer.class
  |                         |--- CustomerPK.class
  |
  |--- TravelAgentBean.jar
  |     |
  |     |--- META-INF 
  |     |     |
  |     |     |--- MENIFEST.MF
  |     |
  |     |--- com
  |            |
  |            |--- titan
  |                  |
  |                  |--- travelagent
  |                         |
  |                         |
  |                         |--- TravelAgentRemote.class
  |                         |
  |                         |--- TravelAgentBean.class

Server Console after successful deployment of the application

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
12:12:24,235 INFO  [JBossASKernel] Created KernelDeployment for: Customer.jar
12:12:24,240 INFO  [JBossASKernel] installing bean: persistence.units:ear=TitanCruises.ear,unitName=titan
12:12:24,240 INFO  [JBossASKernel]   with dependencies:
12:12:24,240 INFO  [JBossASKernel]   and demands:
12:12:24,240 INFO  [JBossASKernel]      jboss.jca:name=TitanDB,service=DataSourceBinding
12:12:24,240 INFO  [JBossASKernel]   and supplies:
12:12:24,240 INFO  [JBossASKernel]      persistence.units:unitName=titan
12:12:24,241 INFO  [JBossASKernel] Added bean(persistence.units:ear=TitanCruises.ear,unitName=titan) to KernelDeployment of: Customer.jar
12:12:24,315 INFO  [STDOUT] ======> Creating interceptor metadata bridge
12:12:24,787 INFO  [JBossASKernel] Created KernelDeployment for: TravelAgentBean.jar
12:12:24,787 INFO  [JBossASKernel] installing bean: jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3
12:12:24,787 INFO  [JBossASKernel]   with dependencies:
12:12:24,788 INFO  [JBossASKernel]   and demands:
12:12:24,788 INFO  [JBossASKernel]      persistence.units:ear=TitanCruises.ear,unitName=titan
12:12:24,788 INFO  [JBossASKernel]      jboss.ejb:service=EJBTimerService
12:12:24,788 INFO  [JBossASKernel]   and supplies:
12:12:24,788 INFO  [JBossASKernel]      jndi:TitanCruises/TravelAgentBean/remote
12:12:24,788 INFO  [JBossASKernel]      jndi:TravelAgentBean
12:12:24,788 INFO  [JBossASKernel]      Class:com.titan.travelagent.TravelAgentRemote
12:12:24,788 INFO  [JBossASKernel]      jndi:TitanCruises/TravelAgentBean/remote-com.titan.travelagent.TravelAgentRemote
12:12:24,788 INFO  [JBossASKernel] Added bean(jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3) to KernelDeployment of: TravelAgentBean.jar
12:12:24,849 INFO  [PersistenceUnitDeployment] Starting persistence unit persistence.units:ear=TitanCruises.ear,unitName=titan
12:12:24,941 INFO  [Version] Hibernate Annotations 3.4.0.CR1
12:12:24,983 INFO  [Environment] Hibernate 3.3.0.CR1
12:12:24,995 INFO  [Environment] hibernate.properties not found
12:12:25,005 INFO  [Environment] Bytecode provider name : javassist
12:12:25,045 INFO  [Environment] using JDK 1.4 java.sql.Timestamp handling
12:12:25,265 INFO  [Version] Hibernate Commons Annotations 3.1.0.CR1
12:12:25,272 INFO  [Version] Hibernate EntityManager 3.4.0.CR1
12:12:25,387 WARN  [Ejb3Configuration] Persistence provider caller does not implement the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null.
12:12:25,529 INFO  [AnnotationBinder] Binding entity from annotated class: com.titan.domain.Customer
12:12:25,633 INFO  [EntityBinder] Bind entity com.titan.domain.Customer on table Customer
12:12:25,737 INFO  [Version] Hibernate Validator 3.1.0.CR1
12:12:26,080 INFO  [ConnectionProviderFactory] Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
12:12:26,084 INFO  [InjectedDataSourceConnectionProvider] Using provided datasource
12:12:26,409 INFO  [SettingsFactory] RDBMS: PostgreSQL, version: 8.1.11
12:12:26,410 INFO  [SettingsFactory] JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 8.1 JDBC3 with SSL (build 412)
12:12:27,007 INFO  [Dialect] Using dialect: org.hibernate.dialect.PostgreSQLDialect
12:12:27,024 INFO  [TransactionFactoryFactory] Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory
12:12:27,031 INFO  [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup
12:12:27,038 INFO  [TransactionManagerLookupFactory] instantiated TransactionManagerLookup
12:12:27,038 INFO  [SettingsFactory] Automatic flush during beforeCompletion(): disabled
12:12:27,038 INFO  [SettingsFactory] Automatic session close at end of transaction: disabled
12:12:27,039 INFO  [SettingsFactory] JDBC batch size: 15
12:12:27,039 INFO  [SettingsFactory] JDBC batch updates for versioned data: disabled
12:12:27,041 INFO  [SettingsFactory] Scrollable result sets: enabled
12:12:27,041 INFO  [SettingsFactory] JDBC3 getGeneratedKeys(): disabled
12:12:27,042 INFO  [SettingsFactory] Connection release mode: auto
12:12:27,044 INFO  [SettingsFactory] Default batch fetch size: 1
12:12:27,044 INFO  [SettingsFactory] Generate SQL with comments: disabled
12:12:27,044 INFO  [SettingsFactory] Order SQL updates by primary key: disabled
12:12:27,044 INFO  [SettingsFactory] Order SQL inserts for batching: disabled
12:12:27,044 INFO  [SettingsFactory] Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
12:12:27,053 INFO  [ASTQueryTranslatorFactory] Using ASTQueryTranslatorFactory
12:12:27,054 INFO  [SettingsFactory] Query language substitutions: {}
12:12:27,054 INFO  [SettingsFactory] JPA-QL strict compliance: enabled
12:12:27,054 INFO  [SettingsFactory] Second-level cache: enabled
12:12:27,054 INFO  [SettingsFactory] Query cache: disabled
12:12:27,076 INFO  [SettingsFactory] Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
12:12:27,077 INFO  [RegionFactoryCacheProviderBridge] Cache provider: org.hibernate.cache.HashtableCacheProvider
12:12:27,081 INFO  [SettingsFactory] Optimize cache for minimal puts: disabled
12:12:27,081 INFO  [SettingsFactory] Cache region prefix: TitanCruises_ear,titan
12:12:27,082 INFO  [SettingsFactory] Structured second-level cache entries: disabled
12:12:27,104 INFO  [SettingsFactory] Statistics: disabled
12:12:27,104 INFO  [SettingsFactory] Deleted entity synthetic identifier rollback: disabled
12:12:27,104 INFO  [SettingsFactory] Default entity-mode: pojo
12:12:27,104 INFO  [SettingsFactory] Named query checking : enabled
12:12:27,198 INFO  [SessionFactoryImpl] building session factory
12:12:27,608 INFO  [SessionFactoryObjectFactory] Factory name: persistence.units:ear=TitanCruises.ear,unitName=titan
12:12:27,611 INFO  [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
12:12:27,616 INFO  [SessionFactoryObjectFactory] Bound factory to JNDI name: persistence.units:ear=TitanCruises.ear,unitName=titan
12:12:27,616 WARN  [SessionFactoryObjectFactory] InitialContext did not implement EventContext
12:12:27,642 INFO  [SchemaExport] Running hbm2ddl schema export
12:12:27,644 INFO  [SchemaExport] exporting generated schema to database
12:12:28,082 ERROR [SchemaExport] Unsuccessful: create table Customer (lastName varchar(255) not null, ssn int8 not null, firstName varchar(255), primary key (lastName, ssn))
12:12:28,082 ERROR [SchemaExport] ERROR: relation "customer" already exists
12:12:28,082 INFO  [SchemaExport] schema export complete
12:12:28,090 INFO  [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
12:12:28,368 INFO  [EJBContainer] STARTED EJB: com.titan.travelagent.TravelAgentBean ejbName: TravelAgentBean

Client’s Console after running the Client.java

1
2
3
Bill
Burke
9999999

References:

“Java Persistence with Hibernate” by Christian Bauer and Gavin King.
“Enterprise JavaBeans 3.0″ by Bill Burke & Richard Monson-Haefel
JBoss Documentations for EJB 3

Share This Post

Leave a Reply