EJB3: Mapping Persistent Objects Example 5

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 5: Embeddable Classes

This example shows the use of @javax.persistence.Embedded annotation to map a persistent property that is a nonentity class.


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
35
36
37
38
39
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");
			Address address = new Address();
			address.setStreet("Clarendon Street");
			address.setCity("Boston");
			address.setState("MA");
			cust.setAddress(address);
 
			long pk = dao.createCustomer(cust);
 
			Address foundAddress = dao.findAddress(pk);
			System.out.println(foundAddress.getStreet());
			System.out.println(foundAddress.getCity());
			System.out.println(foundAddress.getState());
		} 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;
import com.titan.domain.Address;
 
@Remote
public interface TravelAgentRemote {
	public long createCustomer(Customer cust);
	public Address findAddress(long custPk);
}

TravelAgentBean.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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.Address;
 
@Stateless
public class TravelAgentBean implements TravelAgentRemote {
	@PersistenceContext(unitName = "titan")
	private EntityManager manager;
 
	public long createCustomer(Customer cust) {
		manager.persist(cust);
		return cust.getId();
	}
 
	public Address findAddress(long pk) {
		return manager.find(Customer.class, pk).getAddress();
	}
}

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
25
26
27
28
29
30
31
32
package com.titan.domain;
 
import javax.persistence.*;
 
@Entity
public class Customer implements java.io.Serializable {
   private long id;
   private String firstName;
   private String lastName;
   private Address address;
 
   @Id @GeneratedValue
   public long getId() { return id; }
   public void setId(long id) { this.id = id; }
 
   public String getFirstName() { return firstName; }
   public void setFirstName(String first) { this.firstName = first; }
 
   public String getLastName() { return lastName; }
   public void setLastName(String last) { this.lastName = last; }
 
   @Embedded
   @AttributeOverrides({
      @AttributeOverride(name="street", column=@Column(name="STREET")),
      @AttributeOverride(name="city", column=@Column(name="CITY")),
      @AttributeOverride(name="state", column=@Column(name="STATE"))
   })
   public Address getAddress() {
      return address;
   }
   public void setAddress(Address address) { this.address = address; }
}

Address.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.titan.domain;
 
import javax.persistence.*;
 
@Embeddable
public class Address implements java.io.Serializable {
   private String street;
   private String city;
   private String state;
 
   @Column(name="STREET")
   public String getStreet() { return street; }
   public void setStreet(String street) { this.street = street; }
 
   @Column(name="CITY")
   public String getCity() { return city; }
   public void setCity(String city) { this.city = city; }
 
   @Column(name="STATE")
   public String getState() { return state; }
   public void setState(String state) { this.state = state; }
}

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_5">
				<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_5/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_5/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
42
TitanCruises.ear
  |
  |--- META-INF
  |     |
  |     |--- application.xml
  |     |
  |     |--- MENIFEST.MF
  |
  |--- Customer.jar
  |     |
  |     |--- META-INF 
  |     |     |
  |     |     |--- persistence.xml
  |     |     |    
  |     |     |--- MENIFEST.MF
  |     |
  |     |--- com
  |           |
  |           |--- titan
  |                  |
  |                  |--- domain
  |                         |
  |                         |--- Customer.class
  |                         |--- Address.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
12:38:54,517 INFO  [JBossASKernel] Created KernelDeployment for: Customer.jar
12:38:54,549 INFO  [JBossASKernel] installing bean: persistence.units:ear=TitanCruises.ear,unitName=titan
12:38:54,550 INFO  [JBossASKernel]   with dependencies:
12:38:54,550 INFO  [JBossASKernel]   and demands:
12:38:54,551 INFO  [JBossASKernel]      jboss.jca:name=TitanDB,service=DataSourceBinding
12:38:54,551 INFO  [JBossASKernel]   and supplies:
12:38:54,551 INFO  [JBossASKernel]      persistence.units:unitName=titan
12:38:54,552 INFO  [JBossASKernel] Added bean(persistence.units:ear=TitanCruises.ear,unitName=titan) to KernelDeployment of: Customer.jar
12:38:54,686 INFO  [STDOUT] ======> Creating interceptor metadata bridge
12:38:55,466 INFO  [JBossASKernel] Created KernelDeployment for: TravelAgentBean.jar
12:38:55,467 INFO  [JBossASKernel] installing bean: jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3
12:38:55,467 INFO  [JBossASKernel]   with dependencies:
12:38:55,467 INFO  [JBossASKernel]   and demands:
12:38:55,467 INFO  [JBossASKernel]      persistence.units:ear=TitanCruises.ear,unitName=titan
12:38:55,467 INFO  [JBossASKernel]      jboss.ejb:service=EJBTimerService
12:38:55,467 INFO  [JBossASKernel]   and supplies:
12:38:55,467 INFO  [JBossASKernel]      jndi:TitanCruises/TravelAgentBean/remote
12:38:55,467 INFO  [JBossASKernel]      jndi:TravelAgentBean
12:38:55,467 INFO  [JBossASKernel]      Class:com.titan.travelagent.TravelAgentRemote
12:38:55,467 INFO  [JBossASKernel]      jndi:TitanCruises/TravelAgentBean/remote-com.titan.travelagent.TravelAgentRemote
12:38:55,467 INFO  [JBossASKernel] Added bean(jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3) to KernelDeployment of: TravelAgentBean.jar
12:38:55,498 INFO  [PersistenceUnitDeployment] Starting persistence unit persistence.units:ear=TitanCruises.ear,unitName=titan
12:38:55,640 INFO  [Version] Hibernate Annotations 3.4.0.CR1
12:38:55,710 INFO  [Environment] Hibernate 3.3.0.CR1
12:38:55,725 INFO  [Environment] hibernate.properties not found
12:38:55,735 INFO  [Environment] Bytecode provider name : javassist
12:38:55,749 INFO  [Environment] using JDK 1.4 java.sql.Timestamp handling
12:38:55,982 INFO  [Version] Hibernate Commons Annotations 3.1.0.CR1
12:38:55,989 INFO  [Version] Hibernate EntityManager 3.4.0.CR1
12:38:56,098 WARN  [Ejb3Configuration] Persistence provider caller does not implement the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null.
12:38:56,259 INFO  [AnnotationBinder] Binding entity from annotated class: com.titan.domain.Customer
12:38:56,342 INFO  [EntityBinder] Bind entity com.titan.domain.Customer on table Customer
12:38:56,463 INFO  [Version] Hibernate Validator 3.1.0.CR1
12:38:56,819 INFO  [ConnectionProviderFactory] Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
12:38:56,823 INFO  [InjectedDataSourceConnectionProvider] Using provided datasource
12:38:57,931 INFO  [SettingsFactory] RDBMS: PostgreSQL, version: 8.1.11
12:38:57,932 INFO  [SettingsFactory] JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 8.1 JDBC3 with SSL (build 412)
12:38:58,013 INFO  [Dialect] Using dialect: org.hibernate.dialect.PostgreSQLDialect
12:38:58,030 INFO  [TransactionFactoryFactory] Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory
12:38:58,039 INFO  [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup
12:38:58,046 INFO  [TransactionManagerLookupFactory] instantiated TransactionManagerLookup
12:38:58,046 INFO  [SettingsFactory] Automatic flush during beforeCompletion(): disabled
12:38:58,046 INFO  [SettingsFactory] Automatic session close at end of transaction: disabled
12:38:58,046 INFO  [SettingsFactory] JDBC batch size: 15
12:38:58,047 INFO  [SettingsFactory] JDBC batch updates for versioned data: disabled
12:38:58,049 INFO  [SettingsFactory] Scrollable result sets: enabled
12:38:58,049 INFO  [SettingsFactory] JDBC3 getGeneratedKeys(): disabled
12:38:58,049 INFO  [SettingsFactory] Connection release mode: auto
12:38:58,052 INFO  [SettingsFactory] Default batch fetch size: 1
12:38:58,052 INFO  [SettingsFactory] Generate SQL with comments: disabled
12:38:58,052 INFO  [SettingsFactory] Order SQL updates by primary key: disabled
12:38:58,052 INFO  [SettingsFactory] Order SQL inserts for batching: disabled
12:38:58,052 INFO  [SettingsFactory] Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
12:38:58,077 INFO  [ASTQueryTranslatorFactory] Using ASTQueryTranslatorFactory
12:38:58,077 INFO  [SettingsFactory] Query language substitutions: {}
12:38:58,077 INFO  [SettingsFactory] JPA-QL strict compliance: enabled
12:38:58,078 INFO  [SettingsFactory] Second-level cache: enabled
12:38:58,078 INFO  [SettingsFactory] Query cache: disabled
12:38:58,105 INFO  [SettingsFactory] Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
12:38:58,106 INFO  [RegionFactoryCacheProviderBridge] Cache provider: org.hibernate.cache.HashtableCacheProvider
12:38:58,110 INFO  [SettingsFactory] Optimize cache for minimal puts: disabled
12:38:58,111 INFO  [SettingsFactory] Cache region prefix: TitanCruises_ear,titan
12:38:58,111 INFO  [SettingsFactory] Structured second-level cache entries: disabled
12:38:58,135 INFO  [SettingsFactory] Statistics: disabled
12:38:58,135 INFO  [SettingsFactory] Deleted entity synthetic identifier rollback: disabled
12:38:58,135 INFO  [SettingsFactory] Default entity-mode: pojo
12:38:58,135 INFO  [SettingsFactory] Named query checking : enabled
12:38:58,299 INFO  [SessionFactoryImpl] building session factory
12:38:58,762 INFO  [SessionFactoryObjectFactory] Factory name: persistence.units:ear=TitanCruises.ear,unitName=titan
12:38:58,766 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:38:58,771 INFO  [SessionFactoryObjectFactory] Bound factory to JNDI name: persistence.units:ear=TitanCruises.ear,unitName=titan
12:38:58,771 WARN  [SessionFactoryObjectFactory] InitialContext did not implement EventContext
12:38:58,800 INFO  [SchemaExport] Running hbm2ddl schema export
12:38:58,803 INFO  [SchemaExport] exporting generated schema to database
12:38:59,043 INFO  [SchemaExport] schema export complete
12:38:59,044 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:38:59,471 INFO  [EJBContainer] STARTED EJB: com.titan.travelagent.TravelAgentBean ejbName: TravelAgentBean

Client’s Console after running the Client.java

1
2
3
Clarendon Street
Boston
MA

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

One Response to “EJB3: Mapping Persistent Objects Example 5”

  1. Rajesh Says:

    I am getting this error when I tried to create a sample application using ur example

    Attempt to cast instance ejbExample.persistence.Order@18cce4e to PersistenceCapable failed

Leave a Reply