Author: Debu Panda
JpaTemplate
. This sample uses a Spring-enabled EJB 3.0 Session bean
(EmployeeFacade EJB
) that uses a Spring bean(
EmployeeService
bean). The Spring bean uses a Data Access Object (
EmployeeDAO
) that uses Spring's
JpaTemplate
to manipulate entities. The persistence unit is managed by the EJB container by using a container-managed entity manager and passing it to Spring using setter injection. The application uses declarative transaction with EJB 3.0. For simplicity and to demonstrate the dependency injection support in the web container we have used a Servlet (
InsertServlet
) as a controller and it uses dependency injection to inject an instance of
EmployeeFacade
.
@Entity
to mark it as an entity.
@Entity
@Table(name = "EMPLOYEES")
public class Employee implements java.io.Serializable
{
private Long empNo;
private String name;
private double sal;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="EMPNO")
public Long getEmpNo()
{
return empNo;
}
..
}
The entity is configured in a persistence unit named howto
as defined the persistence.xml. Note that the persistence unit uses a datasource with jndi location jdbc/OracleDS
.
The
JpaTemplate
in Spring 2.0 nicely abstracts dealing with EJB 3.0 JPA EntityManager API.
JpaTemplate
to manipulate entities:
public class EmployeeSpringDAO extends JpaDaoSupport implements EmployeeDAO {
public Employee addEmployee(String empName, double sal) {
Employee employee = new Employee();
employee.setEname(empName);
employee.setSal(sal);
this.getJpaTemplate().persist(employee);
return employee;
}
public Employee findEmployee(Long employeeId) {
return (Employee) getJpaTemplate().find(Employee.class,employeeId);
}
}
EmployeeDAO
. It uses setter injection to get an instance of
EmployeeDAO
. The following is the code for the EmployeeServiceBean:
public class EmployeeServiceBean implements EmployeeService {
protected EmployeeDAO employeeDAO ;
public void setEmployeeDAO(EmployeeDAO employeeDAO) {
this.employeeDAO = employeeDAO;
}
public Employee addEmployee(String empName, Double sal){
return (Employee) this.employeeDAO.addEmployee(empName, sal);
}
public Employee findEmployeeByEmpNo(Long empNo) {
return (Employee) this.employeeDAO.findEmployee(empNo);
}
}
The EmployeeFacadeBean extends Spring's
AbstractStatelessSessionBean
and retrieves the EmployeeServiceBean from the bean factory.
@PersistenceContext(name="howto/EntityManager",unitName="howto")
@Stateless
public class EmployeeFacadeBean extends AbstractStatelessSessionBean implements EmployeeFacade {
EmployeeServiceBean empService;
protected void onEjbCreate() {
empService = (EmployeeServiceBean) getBeanFactory().getBean("empService");
}
public Employee addEmployee(String empName, double sal) {
return empService.addEmployee(empName,sal);
}
public Employee findEmployeeByEmpNo(Long empNo){
return empService.findEmployeeByEmpNo(empNo);
}
}
onEjbCreate
method that retrieves
EmployeeServiceBean
instance.
ejb/BeanFactoryPath
in the deployment descriptor (ejb-jar.xml) as follows:
<session>
<ejb-name>EmployeeFacadeBean</ejb-name>
<env-entry>
<env-entry-name>ejb/BeanFactoryPath</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>/howto-service.xml</env-entry-value>
</env-entry>
</session>
howto-service.xml
contains the Spring configuration. Note that the DAO uses a container-managed entity manager and is retrieved from the ENC using the
JndiObjectFactoryBean
as follows:
<bean id="entityManager" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/howto/EntityManager</value>
</property>
<property name="resourceRef">
<value>true</value>
</property>
</bean>
EmployeeDAO
. Note that the EmployeeSpringDAO refers to enityManager bean that we defined earlier as follows:
<bean id="employeeDAO" class="oracle.ejb30.EmployeeSpringDAO"
autowire="byType">
<property name="entityManager" ref="entityManager"/>
</bean>
<bean id="empService" class="oracle.ejb30.EmployeeServiceBean">
<property name="employeeDAO">
<ref bean="employeeDAO"/>
</property>
</bean>
EmployeeFacadeBean
) invokes the EmployeeService bean from the bean factory
empService = (EmployeeServiceBean) getBeanFactory().getBean("empService");
<bean id="howToMbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="defaultDomain" value="SpringHowTo" />
</bean>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=empService" value-ref="empService" />
<entry key="bean:name=employeeDAO" value-ref="employeeDAO" />
</map>
</property>
<property name="server" ref="howToMbeanServer" />
</bean>
- Link to other EJB 3.0 Resources on OTN
- Link to other JPA Howto's on OTN
- Oracle Application Server 10g 10.1.3.1.
- Sun JDK version 1.5 or above, available
here - Spring 2.0
- Any HTML browser like Mozilla, Microsoft Internet Explorer, Netscape, etc.
- A relational database such as Oracle.
- %ORACLE_HOME% - The directory where you installed the Oracle Application Server 10g 10.1.3 .1
- %SPRING_HOME% - The directory where Spring Framework version 2.0 is installed
- %JAVA_HOME% - The directory where your JDK is installed
- %HOWTO_HOME% - The directory where this demo is unzipped
- build - temporary directory created during the build
- log - temporary directory holding build/deploy logs
- etc - all necessary files to package the application
- lib - holds the application archives that could be deployed
- doc - the How-to document and Javadoc's
- how-to-ejb30-jpa-spring.html - this How-to page
- src - the source of the demo
- ejb - contains the sample entity, Spring bean and DAO
- web- contains application
- %ORACLE_HOME% - The directory where you installed OC4J.
- %SPRING_HOME% - The directory where you installed Spring 2.0
- %JAVA_HOME% - The directory where you installed the J2SE 5.0
- %PATH% - includes %ORACLE_HOME% /ant/bin
jndi-location
as
jdbc/OracleDS
)to be configured to connect to the database where you want to persist the entity. The persistence unit is configured to use automatic table creation feature of Oracle TopLink Essentials. For details see
http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-extensions.html.
For OC4J, you must configure a datasource in the %ORACLE_HOME%/j2ee/home/config/data-sources.xml file and point it at the schema.
<connection-pool name="ScottConnectionPool">
<connection-factory factory-class="oracle.jdbc.pool.OracleDataSource"
user="scott"
password="tiger"
url="jdbc:oracle:thin:@localhost:1521:ORCL" >
</connection-factory>
</connection-pool><managed-data-source name="OracleManagedDS"
connection-pool-name="ScottConnectionPool"
jndi-name="jdbc/OracleDS"
/>You can create the JDBC resources by using ANT tasks. Make sure you change the database configurations (db.host, db.sid, db.port, db.user, db.password) in ant-oracle.properties file.Ensure $ORACLE_HOME/ant/bin is included in your PATH environment variable and then use the following command:>ant configure-ds
>%ORACLE_HOME%/bin/oc4j -start
> %ORACLE_HOME%/opmn/bin/opmnctl startall
Edit ant-oracle.properties (in the demodirectory) and ensure the following properties are set to the correct values, as indicated below for OC4J standalone:
- oc4j.host: host where OC4J is running (default localhost)
- oc4j.admin.port: RMI port number (default 23791)
- oc4j.admin.user: admin user name (default oc4jadmin)
- oc4j.admin.password: admin user password (default welcome)
- oc4j.binding.module: website name where deployed web modules are bound (default http-web-site)
- opmn.host: the hostname/IP where OracleAS is running (default localhost)
- opmn.port: OPMN request port (default 6003) for the OracleAS install
- oc4j.instance: admin user name (default oc4jadmin)
>ant
>ant deploy
addEmployee
method
EmployeeFacade. The EmployeeFacade bean uses the EmployeeServiceBean (Spring managed Bean) that in turns uses Spring
JpaTemplate
to persist the entity instance.
You will be redirected to a success page if your record was inserted successfully. You can also check the database table to ensure the record was created.
- Develop a simple Spring enabled EJB 3.0 Session Bean
- Use the container-managed EntityManager with Spring JpaTemplate
- Deploy an execute a sample application using Spring-enabled EJB 3.0 Session bean, JPA Integration with Spring on Oracle Application Server 10g 10.1.3.1
<persistence-unit name="howto">
<jta-data-source>jdbc/OracleDS</jta-data-source>
<properties>
<property name = "toplink.ddl-generation"
value = "drop-and-create-tables"/>
<property name = "toplink.ddl-generation.output-mode" value = "database"/>
</properties>
</persistence-unit>
</persistence>