EJB3: Mapping Persistent Objects Example 3
by admin ~ October 21, 2008
Example 3: @EmbeddedId
This example shows the use of @javax.persistence.EmbeddedId to map a primary key class to the database and also the use of @javax.persistence.Transient annotation.
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 | package com.titan.clients; import com.titan.travelagent.TravelAgentRemote; import com.titan.domain.*; import javax.naming.InitialContext; import javax.naming.Context; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; public class Client { public static void main(String[] args) { try { Context jndiContext = getInitialContext(); Object ref = jndiContext .lookup("TitanCruises/TravelAgentBean/remote"); TravelAgentRemote dao = (TravelAgentRemote) ref; CustomerPK pk = new CustomerPK("Burke", 9999999); Customer cust = new Customer(); cust.setPk(pk); cust.setFirstName("Bill"); 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 | 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 22 23 | 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 25 26 | package com.titan.domain; import javax.persistence.*; @Entity public class Customer implements java.io.Serializable { private String firstName; private CustomerPK pk; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } @EmbeddedId @AttributeOverrides({ @AttributeOverride(name="lastName", column=@Column(name="LAST_NAME")), @AttributeOverride(name="ssn", column=@Column(name="SSN")) }) public CustomerPK getPk() { return pk; } public void setPk(CustomerPK pk) { this.pk = pk; } @Transient public String getLastName() { return pk.getLastName(); } @Transient public long getSsn() { return pk.getSsn(); } } |
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | package com.titan.domain; import javax.persistence.*; @Embeddable 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; } @Column(name = "CUSTOMER_LAST_NAME") public String getLastName() { return this.lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @Column(name = "CUSTOMER_SSN") 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> |
Data Source file : postgres-TitanDB-ds.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?xml version="1.0" encoding="UTF-8"?> <datasources> <local-tx-datasource> <jndi-name>TitanDB</jndi-name> <use-java-context>true</use-java-context> <connection-url>jdbc:postgresql://127.0.0.1:5432/ejb3db</connection-url> <driver-class>org.postgresql.Driver</driver-class> <user-name>ranjan</user-name> <password>ranjan</password> <metadata> <type-mapping>PostgreSQL 8.0</type-mapping> </metadata> </local-tx-datasource> </datasources> |
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_3"> <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_3/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_3/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 | 12:25:44,729 INFO [JBossASKernel] Created KernelDeployment for: Customer.jar 12:25:44,734 INFO [JBossASKernel] installing bean: persistence.units:ear=TitanCruises.ear,unitName=titan 12:25:44,734 INFO [JBossASKernel] with dependencies: 12:25:44,734 INFO [JBossASKernel] and demands: 12:25:44,735 INFO [JBossASKernel] jboss.jca:name=TitanDB,service=DataSourceBinding 12:25:44,735 INFO [JBossASKernel] and supplies: 12:25:44,735 INFO [JBossASKernel] persistence.units:unitName=titan 12:25:44,735 INFO [JBossASKernel] Added bean(persistence.units:ear=TitanCruises.ear,unitName=titan) to KernelDeployment of: Customer.jar 12:25:44,824 INFO [STDOUT] ======> Creating interceptor metadata bridge 12:25:45,487 INFO [JBossASKernel] Created KernelDeployment for: TravelAgentBean.jar 12:25:45,488 INFO [JBossASKernel] installing bean: jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3 12:25:45,488 INFO [JBossASKernel] with dependencies: 12:25:45,488 INFO [JBossASKernel] and demands: 12:25:45,488 INFO [JBossASKernel] persistence.units:ear=TitanCruises.ear,unitName=titan 12:25:45,488 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 12:25:45,488 INFO [JBossASKernel] and supplies: 12:25:45,488 INFO [JBossASKernel] jndi:TitanCruises/TravelAgentBean/remote 12:25:45,488 INFO [JBossASKernel] jndi:TravelAgentBean 12:25:45,488 INFO [JBossASKernel] Class:com.titan.travelagent.TravelAgentRemote 12:25:45,488 INFO [JBossASKernel] jndi:TitanCruises/TravelAgentBean/remote-com.titan.travelagent.TravelAgentRemote 12:25:45,488 INFO [JBossASKernel] Added bean(jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3) to KernelDeployment of: TravelAgentBean.jar 12:25:45,563 INFO [PersistenceUnitDeployment] Starting persistence unit persistence.units:ear=TitanCruises.ear,unitName=titan 12:25:45,718 INFO [Version] Hibernate Annotations 3.4.0.CR1 12:25:45,753 INFO [Environment] Hibernate 3.3.0.CR1 12:25:45,763 INFO [Environment] hibernate.properties not found 12:25:45,786 INFO [Environment] Bytecode provider name : javassist 12:25:45,804 INFO [Environment] using JDK 1.4 java.sql.Timestamp handling 12:25:46,101 INFO [Version] Hibernate Commons Annotations 3.1.0.CR1 12:25:46,108 INFO [Version] Hibernate EntityManager 3.4.0.CR1 12:25:46,220 WARN [Ejb3Configuration] Persistence provider caller does not implement the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null. 12:25:46,356 INFO [AnnotationBinder] Binding entity from annotated class: com.titan.domain.Customer 12:25:46,451 INFO [EntityBinder] Bind entity com.titan.domain.Customer on table Customer 12:25:46,557 INFO [Version] Hibernate Validator 3.1.0.CR1 12:25:46,892 INFO [ConnectionProviderFactory] Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider 12:25:46,897 INFO [InjectedDataSourceConnectionProvider] Using provided datasource 12:25:47,688 INFO [SettingsFactory] RDBMS: PostgreSQL, version: 8.1.11 12:25:47,688 INFO [SettingsFactory] JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 8.1 JDBC3 with SSL (build 412) 12:25:47,745 INFO [Dialect] Using dialect: org.hibernate.dialect.PostgreSQLDialect 12:25:47,761 INFO [TransactionFactoryFactory] Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory 12:25:47,768 INFO [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup 12:25:47,775 INFO [TransactionManagerLookupFactory] instantiated TransactionManagerLookup 12:25:47,775 INFO [SettingsFactory] Automatic flush during beforeCompletion(): disabled 12:25:47,775 INFO [SettingsFactory] Automatic session close at end of transaction: disabled 12:25:47,775 INFO [SettingsFactory] JDBC batch size: 15 12:25:47,775 INFO [SettingsFactory] JDBC batch updates for versioned data: disabled 12:25:47,777 INFO [SettingsFactory] Scrollable result sets: enabled 12:25:47,778 INFO [SettingsFactory] JDBC3 getGeneratedKeys(): disabled 12:25:47,778 INFO [SettingsFactory] Connection release mode: auto 12:25:47,780 INFO [SettingsFactory] Default batch fetch size: 1 12:25:47,780 INFO [SettingsFactory] Generate SQL with comments: disabled 12:25:47,780 INFO [SettingsFactory] Order SQL updates by primary key: disabled 12:25:47,780 INFO [SettingsFactory] Order SQL inserts for batching: disabled 12:25:47,780 INFO [SettingsFactory] Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory 12:25:47,789 INFO [ASTQueryTranslatorFactory] Using ASTQueryTranslatorFactory 12:25:47,789 INFO [SettingsFactory] Query language substitutions: {} 12:25:47,789 INFO [SettingsFactory] JPA-QL strict compliance: enabled 12:25:47,789 INFO [SettingsFactory] Second-level cache: enabled 12:25:47,789 INFO [SettingsFactory] Query cache: disabled 12:25:47,811 INFO [SettingsFactory] Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge 12:25:47,811 INFO [RegionFactoryCacheProviderBridge] Cache provider: org.hibernate.cache.HashtableCacheProvider 12:25:47,816 INFO [SettingsFactory] Optimize cache for minimal puts: disabled 12:25:47,816 INFO [SettingsFactory] Cache region prefix: TitanCruises_ear,titan 12:25:47,816 INFO [SettingsFactory] Structured second-level cache entries: disabled 12:25:47,838 INFO [SettingsFactory] Statistics: disabled 12:25:47,838 INFO [SettingsFactory] Deleted entity synthetic identifier rollback: disabled 12:25:47,838 INFO [SettingsFactory] Default entity-mode: pojo 12:25:47,838 INFO [SettingsFactory] Named query checking : enabled 12:25:47,944 INFO [SessionFactoryImpl] building session factory 12:25:48,351 INFO [SessionFactoryObjectFactory] Factory name: persistence.units:ear=TitanCruises.ear,unitName=titan 12:25:48,355 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:25:48,360 INFO [SessionFactoryObjectFactory] Bound factory to JNDI name: persistence.units:ear=TitanCruises.ear,unitName=titan 12:25:48,360 WARN [SessionFactoryObjectFactory] InitialContext did not implement EventContext 12:25:48,385 INFO [SchemaExport] Running hbm2ddl schema export 12:25:48,388 INFO [SchemaExport] exporting generated schema to database 12:25:48,444 INFO [SchemaExport] schema export complete 12:25:48,445 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:25:48,752 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



Leave a Reply