EJB3: Mapping Persistent Objects Example 1
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 1: Basic Property Mappings
This example shows the use of @Temporal, @Lob and @Enumerated mapping types.
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"); cust.setCustomerType(CustomerType.BIG_SPENDAH); JPEG oneUglyDude = new JPEG(); cust.setPicture(oneUglyDude); int pk = dao.createCustomer(cust); cust = dao.findCustomer(pk); System.out.println(cust.getFirstName()); System.out.println(cust.getLastName()); System.out.println(cust.getCustomerType()); } 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 int createCustomer(Customer cabin); public Customer findCustomer(int id); } |
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 int createCustomer(Customer customer) { manager.persist(customer); return customer.getId(); } public Customer findCustomer(int pKey) { return manager.find(Customer.class, pKey); } } |
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 | package com.titan.domain; import java.util.Date; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity @Table(name="CUSTOMER_TABLE") public class Customer implements java.io.Serializable { private int id; private String lastName; private String firstName; private CustomerType customerType; private Date timeCreated = new Date(); private JPEG picture; @Id @GeneratedValue @Column(name="CUST_ID") public int getId(){return id;} public void setId(int pk) {id = pk;} public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } @Enumerated(EnumType.STRING) public CustomerType getCustomerType() { return customerType;} public void setCustomerType(CustomerType customerType) {this.customerType = customerType;} @Temporal(TemporalType.TIME) public Date getTimeCreated(){ return timeCreated; } public void setTimeCreated(Date time) { timeCreated = time; } @Lob @Basic(fetch=FetchType.LAZY) public JPEG getPicture() { return picture; } public void setPicture(JPEG jpeg) { picture = jpeg;} } |
CustomerType.java
1 2 3 4 5 6 7 | package com.titan.domain; public enum CustomerType { UNREGISTERED, REGISTERED, BIG_SPENDAH } |
JPEG.java
1 2 3 4 5 | package com.titan.domain; public class JPEG implements java.io.Serializable { public JPEG() {} } |
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>java:/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"> <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/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/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 | |--- CustomerType.class | |--- JPEG.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 | 11:59:05,069 INFO [JBossASKernel] Created KernelDeployment for: Customer.jar 11:59:05,074 INFO [JBossASKernel] installing bean: persistence.units:ear=TitanCruises.ear,unitName=titan 11:59:05,074 INFO [JBossASKernel] with dependencies: 11:59:05,074 INFO [JBossASKernel] and demands: 11:59:05,074 INFO [JBossASKernel] jboss.jca:name=TitanDB,service=DataSourceBinding 11:59:05,074 INFO [JBossASKernel] and supplies: 11:59:05,075 INFO [JBossASKernel] persistence.units:unitName=titan 11:59:05,075 INFO [JBossASKernel] Added bean(persistence.units:ear=TitanCruises.ear,unitName=titan) to KernelDeployment of: Customer.jar 11:59:05,165 INFO [STDOUT] ======> Creating interceptor metadata bridge 11:59:05,566 INFO [JBossASKernel] Created KernelDeployment for: TravelAgentBean.jar 11:59:05,566 INFO [JBossASKernel] installing bean: jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3 11:59:05,566 INFO [JBossASKernel] with dependencies: 11:59:05,566 INFO [JBossASKernel] and demands: 11:59:05,566 INFO [JBossASKernel] persistence.units:ear=TitanCruises.ear,unitName=titan 11:59:05,566 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 11:59:05,567 INFO [JBossASKernel] and supplies: 11:59:05,567 INFO [JBossASKernel] jndi:TitanCruises/TravelAgentBean/remote 11:59:05,567 INFO [JBossASKernel] jndi:TravelAgentBean 11:59:05,567 INFO [JBossASKernel] Class:com.titan.travelagent.TravelAgentRemote 11:59:05,567 INFO [JBossASKernel] jndi:TitanCruises/TravelAgentBean/remote-com.titan.travelagent.TravelAgentRemote 11:59:05,567 INFO [JBossASKernel] Added bean(jboss.j2ee:ear=TitanCruises.ear,jar=TravelAgentBean.jar,name=TravelAgentBean,service=EJB3) to KernelDeployment of: TravelAgentBean.jar 11:59:05,598 INFO [PersistenceUnitDeployment] Starting persistence unit persistence.units:ear=TitanCruises.ear,unitName=titan 11:59:05,693 INFO [Version] Hibernate Annotations 3.4.0.CR1 11:59:05,729 INFO [Environment] Hibernate 3.3.0.CR1 11:59:05,738 INFO [Environment] hibernate.properties not found 11:59:05,745 INFO [Environment] Bytecode provider name : javassist 11:59:05,758 INFO [Environment] using JDK 1.4 java.sql.Timestamp handling 11:59:05,980 INFO [Version] Hibernate Commons Annotations 3.1.0.CR1 11:59:05,987 INFO [Version] Hibernate EntityManager 3.4.0.CR1 11:59:06,092 WARN [Ejb3Configuration] Persistence provider caller does not implement the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null. 11:59:06,246 INFO [AnnotationBinder] Binding entity from annotated class: com.titan.domain.Customer 11:59:06,328 INFO [EntityBinder] Bind entity com.titan.domain.Customer on table CUSTOMER_TABLE 11:59:06,458 INFO [Version] Hibernate Validator 3.1.0.CR1 11:59:06,729 INFO [ConnectionProviderFactory] Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider 11:59:06,733 INFO [InjectedDataSourceConnectionProvider] Using provided datasource 11:59:06,958 INFO [SettingsFactory] RDBMS: PostgreSQL, version: 8.1.11 11:59:06,958 INFO [SettingsFactory] JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 8.1 JDBC3 with SSL (build 412) 11:59:07,537 INFO [Dialect] Using dialect: org.hibernate.dialect.PostgreSQLDialect 11:59:07,553 INFO [TransactionFactoryFactory] Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory 11:59:07,560 INFO [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup 11:59:07,567 INFO [TransactionManagerLookupFactory] instantiated TransactionManagerLookup 11:59:07,567 INFO [SettingsFactory] Automatic flush during beforeCompletion(): disabled 11:59:07,567 INFO [SettingsFactory] Automatic session close at end of transaction: disabled 11:59:07,568 INFO [SettingsFactory] JDBC batch size: 15 11:59:07,568 INFO [SettingsFactory] JDBC batch updates for versioned data: disabled 11:59:07,570 INFO [SettingsFactory] Scrollable result sets: enabled 11:59:07,570 INFO [SettingsFactory] JDBC3 getGeneratedKeys(): disabled 11:59:07,570 INFO [SettingsFactory] Connection release mode: auto 11:59:07,573 INFO [SettingsFactory] Default batch fetch size: 1 11:59:07,573 INFO [SettingsFactory] Generate SQL with comments: disabled 11:59:07,573 INFO [SettingsFactory] Order SQL updates by primary key: disabled 11:59:07,573 INFO [SettingsFactory] Order SQL inserts for batching: disabled 11:59:07,573 INFO [SettingsFactory] Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory 11:59:07,584 INFO [ASTQueryTranslatorFactory] Using ASTQueryTranslatorFactory 11:59:07,584 INFO [SettingsFactory] Query language substitutions: {} 11:59:07,584 INFO [SettingsFactory] JPA-QL strict compliance: enabled 11:59:07,584 INFO [SettingsFactory] Second-level cache: enabled 11:59:07,584 INFO [SettingsFactory] Query cache: disabled 11:59:07,607 INFO [SettingsFactory] Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge 11:59:07,607 INFO [RegionFactoryCacheProviderBridge] Cache provider: org.hibernate.cache.HashtableCacheProvider 11:59:07,612 INFO [SettingsFactory] Optimize cache for minimal puts: disabled 11:59:07,612 INFO [SettingsFactory] Cache region prefix: TitanCruises_ear,titan 11:59:07,612 INFO [SettingsFactory] Structured second-level cache entries: disabled 11:59:07,635 INFO [SettingsFactory] Statistics: disabled 11:59:07,635 INFO [SettingsFactory] Deleted entity synthetic identifier rollback: disabled 11:59:07,637 INFO [SettingsFactory] Default entity-mode: pojo 11:59:07,637 INFO [SettingsFactory] Named query checking : enabled 11:59:07,731 INFO [SessionFactoryImpl] building session factory 11:59:08,201 INFO [SessionFactoryObjectFactory] Factory name: persistence.units:ear=TitanCruises.ear,unitName=titan 11:59:08,204 INFO [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces} 11:59:08,209 INFO [SessionFactoryObjectFactory] Bound factory to JNDI name: persistence.units:ear=TitanCruises.ear,unitName=titan 11:59:08,209 WARN [SessionFactoryObjectFactory] InitialContext did not implement EventContext 11:59:08,235 INFO [SchemaExport] Running hbm2ddl schema export 11:59:08,237 INFO [SchemaExport] exporting generated schema to database 11:59:08,260 INFO [SchemaExport] schema export complete 11:59:08,260 INFO [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces} 11:59:08,698 INFO [EJBContainer] STARTED EJB: com.titan.travelagent.TravelAgentBean ejbName: TravelAgentBean |
Client’s Console after running the Client.java
1 2 3 | Bill Burke BIG_SPENDAH |
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



October 23rd, 2008 at 7:47 am
Hi ranjan,
I am in great trouble i am new to ejb3.0 .i am using jboss server 4.2 . while doing mapping in ejb3.0, i am getting folowing exceptions.org.hibernate.annotation exception.how to run mappings in ejb3.0 on jboss4.2.please help me.
Thank u
K.Ramu
October 23rd, 2008 at 11:22 pm
@Ramu
See, how the EJB 3.0 works, is same whether you are on 4.2 or 5.x. The only difference is that where you find the libraries and the way it is packaged. In JBoss 4.x, the packaging is not standard. Even mappings are not specific to the server version. I guess the problem you are facing is related to libraries.