EJB3: Mapping Persistent Objects Example 4
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 4: Multitable Mappings
This example shows the use of @javax.persistence.SecondaryTable annotation to map one entity class to multiple tables.
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 40 | 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.setStreet("Clarendon Street"); cust.setCity("Boston"); cust.setState("MA"); long pk = dao.createCustomer(cust); System.out.println("pk :" + pk); cust = dao.findCustomer(pk); System.out.println(cust.getFirstName()); System.out.println(cust.getLastName()); System.out.println(cust.getStreet()); System.out.println(cust.getCity()); System.out.println(cust.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 | package com.titan.travelagent; import javax.ejb.Remote; import com.titan.domain.Customer; @Remote public interface TravelAgentRemote { public long createCustomer(Customer cust); public Customer findCustomer(long pk); } |
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; @Stateless public class TravelAgentBean implements TravelAgentRemote { @PersistenceContext(unitName = "titan") private EntityManager manager; public long createCustomer(Customer cust) { manager.persist(cust); return cust.getId(); } public Customer findCustomer(long pk) { 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 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 | package com.titan.domain; import javax.persistence.*; @Entity @Table(name = "CUSTOMER_TABLE") @SecondaryTable(name = "ADDRESS_TABLE", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "ADDRESS_ID") }) public class Customer implements java.io.Serializable { private long id; private String firstName; private String lastName; private String street; private String city; private String state; @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; } @Column(name = "STREET", table = "ADDRESS_TABLE") public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } @Column(name = "CITY", table = "ADDRESS_TABLE") public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Column(name = "STATE", table = "ADDRESS_TABLE") public String getState() { return state; } public void setState(String state) { this.state = state; } } |
persistence.properties
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 32 | <?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_4"> <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_4/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_4/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 | TitanCruises.ear | |--- META-INF | | | |--- application.xml | | | |--- MENIFEST.MF | |--- Customer.jar | | | |--- META-INF | | | | | |--- persistence.xml | | | | | |--- MENIFEST.MF | | | |--- com | | | |--- titan | | | |--- domain | | | |--- Customer.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 | 12:31:25,923 INFO [JBossASKernel] Created KernelDeployment for: Customer.jar 12:31:25,931 INFO [JBossASKernel] installing bean: persistence.units:ear=TitanCruises.ear,unitName=titan 12:31:25,931 INFO [JBossASKernel] with dependencies: 12:31:25,931 INFO [JBossASKernel] and demands: 12:31:25,931 INFO [JBossASKernel] jboss.jca:name=TitanDB,service=DataSourceBinding 12:31:25,931 INFO [JBossASKernel] and supplies: 12:31:25,932 INFO [JBossASKernel] persistence.units:unitName=titan 12:31:25,932 INFO [JBossASKernel] Added bean(persistence.units:ear=TitanCruises.ear,unitName=titan) to KernelDeployment of: Customer.jar 12:31:26,052 INFO [STDOUT] ======> Creating interceptor metadata bridge 12:31:26,623 INFO [JBossASKernel] Created KernelDeployment for: TravelAgentBean.jar 12:31:26,623 INFO [JBossASKernel] installing bean: jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3 12:31:26,623 INFO [JBossASKernel] with dependencies: 12:31:26,624 INFO [JBossASKernel] and demands: 12:31:26,624 INFO [JBossASKernel] persistence.units:ear=TitanCruises.ear,unitName=titan 12:31:26,624 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 12:31:26,624 INFO [JBossASKernel] and supplies: 12:31:26,624 INFO [JBossASKernel] jndi:TitanCruises/TravelAgentBean/remote 12:31:26,624 INFO [JBossASKernel] jndi:TravelAgentBean 12:31:26,624 INFO [JBossASKernel] Class:com.titan.travelagent.TravelAgentRemote 12:31:26,624 INFO [JBossASKernel] jndi:TitanCruises/TravelAgentBean/remote-com.titan.travelagent.TravelAgentRemote 12:31:26,624 INFO [JBossASKernel] Added bean(jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3) to KernelDeployment of: TravelAgentBean.jar 12:31:26,662 INFO [PersistenceUnitDeployment] Starting persistence unit persistence.units:ear=TitanCruises.ear,unitName=titan 12:31:26,859 INFO [Version] Hibernate Annotations 3.4.0.CR1 12:31:26,897 INFO [Environment] Hibernate 3.3.0.CR1 12:31:26,908 INFO [Environment] hibernate.properties not found 12:31:26,915 INFO [Environment] Bytecode provider name : javassist 12:31:26,948 INFO [Environment] using JDK 1.4 java.sql.Timestamp handling 12:31:27,191 INFO [Version] Hibernate Commons Annotations 3.1.0.CR1 12:31:27,198 INFO [Version] Hibernate EntityManager 3.4.0.CR1 12:31:27,357 WARN [Ejb3Configuration] Persistence provider caller does not implement the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null. 12:31:27,607 INFO [AnnotationBinder] Binding entity from annotated class: com.titan.domain.Customer 12:31:27,705 INFO [EntityBinder] Bind entity com.titan.domain.Customer on table CUSTOMER_TABLE 12:31:27,718 INFO [EntityBinder] Adding secondary table to entity com.titan.domain.Customer -> ADDRESS_TABLE 12:31:27,827 INFO [Version] Hibernate Validator 3.1.0.CR1 12:31:28,100 INFO [ConnectionProviderFactory] Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider 12:31:28,104 INFO [InjectedDataSourceConnectionProvider] Using provided datasource 12:31:28,524 INFO [SettingsFactory] RDBMS: PostgreSQL, version: 8.1.11 12:31:28,525 INFO [SettingsFactory] JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 8.1 JDBC3 with SSL (build 412) 12:31:29,102 INFO [Dialect] Using dialect: org.hibernate.dialect.PostgreSQLDialect 12:31:29,119 INFO [TransactionFactoryFactory] Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory 12:31:29,126 INFO [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup 12:31:29,133 INFO [TransactionManagerLookupFactory] instantiated TransactionManagerLookup 12:31:29,133 INFO [SettingsFactory] Automatic flush during beforeCompletion(): disabled 12:31:29,133 INFO [SettingsFactory] Automatic session close at end of transaction: disabled 12:31:29,133 INFO [SettingsFactory] JDBC batch size: 15 12:31:29,133 INFO [SettingsFactory] JDBC batch updates for versioned data: disabled 12:31:29,136 INFO [SettingsFactory] Scrollable result sets: enabled 12:31:29,136 INFO [SettingsFactory] JDBC3 getGeneratedKeys(): disabled 12:31:29,136 INFO [SettingsFactory] Connection release mode: auto 12:31:29,139 INFO [SettingsFactory] Default batch fetch size: 1 12:31:29,139 INFO [SettingsFactory] Generate SQL with comments: disabled 12:31:29,139 INFO [SettingsFactory] Order SQL updates by primary key: disabled 12:31:29,139 INFO [SettingsFactory] Order SQL inserts for batching: disabled 12:31:29,139 INFO [SettingsFactory] Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory 12:31:29,148 INFO [ASTQueryTranslatorFactory] Using ASTQueryTranslatorFactory 12:31:29,149 INFO [SettingsFactory] Query language substitutions: {} 12:31:29,149 INFO [SettingsFactory] JPA-QL strict compliance: enabled 12:31:29,149 INFO [SettingsFactory] Second-level cache: enabled 12:31:29,149 INFO [SettingsFactory] Query cache: disabled 12:31:29,171 INFO [SettingsFactory] Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge 12:31:29,172 INFO [RegionFactoryCacheProviderBridge] Cache provider: org.hibernate.cache.HashtableCacheProvider 12:31:29,176 INFO [SettingsFactory] Optimize cache for minimal puts: disabled 12:31:29,176 INFO [SettingsFactory] Cache region prefix: TitanCruises_ear,titan 12:31:29,176 INFO [SettingsFactory] Structured second-level cache entries: disabled 12:31:29,200 INFO [SettingsFactory] Statistics: disabled 12:31:29,200 INFO [SettingsFactory] Deleted entity synthetic identifier rollback: disabled 12:31:29,202 INFO [SettingsFactory] Default entity-mode: pojo 12:31:29,202 INFO [SettingsFactory] Named query checking : enabled 12:31:29,328 INFO [SessionFactoryImpl] building session factory 12:31:29,868 INFO [SessionFactoryObjectFactory] Factory name: persistence.units:ear=TitanCruises.ear,unitName=titan 12:31:29,872 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:31:29,876 INFO [SessionFactoryObjectFactory] Bound factory to JNDI name: persistence.units:ear=TitanCruises.ear,unitName=titan 12:31:29,876 WARN [SessionFactoryObjectFactory] InitialContext did not implement EventContext 12:31:29,920 INFO [SchemaExport] Running hbm2ddl schema export 12:31:29,923 INFO [SchemaExport] exporting generated schema to database 12:31:30,389 INFO [SchemaExport] schema export complete 12:31:30,390 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:31:30,986 INFO [EJBContainer] STARTED EJB: com.titan.travelagent.TravelAgentBean ejbName: TravelAgentBean |
Client’s Console after running the Client.java
1 2 3 4 5 6 | pk :1 Bill Burke 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



Leave a Reply