Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


The Java EE Application as an EJB/Spring/Hibernate Hybrid : Page 3

Java EE 5 provides all the features you need to build a robust enterprise application right in an EJB 3.0 container, but incorporating the relative strengths of Spring and Hibernate can further improve the productivity and quality of your application.


WEBINAR: On-Demand

Unleash Your DevOps Strategy by Synchronizing Application and Database Changes REGISTER >

Invoking EJB 3.0 Stateless Session Beans
The traditional approach for invoking stateless session beans (SLSB) has been implementing the service locater pattern and then referencing the local (or remote) interface. EJB 3.0 makes the whole invocation process as easy as adding an annotation (@EJB) in the calling class. Note: For local interfaces, GlassFish requires you to provide name and bean interface parameters (for example, name="profejbref", beanInterface=com.app.domain.ejb.ProfileManager.class) and look up the local EJB reference in the private namespace (java:comp/env). Local EJBs are not registered in the global JNDI. Not all application servers require this.

To enable Spring to seamlessly include the SLSB in the application example's presentation tier controller, you configure it down to a Spring-managed bean. Simply add the following entry in the Spring application context file applicationContext.xml, which is located in the WEB-INF directory:

<bean id="profileMgr" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="ejb/ProfMgrEJB" /> </bean>

With the following snippet, you now inject the above Spring-managed EJB into the controller class and declare it in springapp-servlet.xml, just like any other Spring dependency injection wiring, with the reference being available through a getter method:

<bean id="springAppController" class="com.app.controller.SpringAppController"> <property name="profileMgr"> <ref bean="profileMgr" /> </property> </bean>

Note that the presentation tier has no references to EJBs or any other constructs. All these references are taken out to the Spring configuration file. A remote EJB 3.0 SLSB can be looked up easily in the global JNDI, which the container uses to register remote SLSB.

The Spring Pitchfork project is an attempt to provide support for the Java EE 5 programming model, which includes support for EJB annotations. It currently supports WebLogic application server, but hopefully it will offer full-featured support and integration with all application servers in the near future. Until then, you can use the above process.

Building the Domain Tier with EJB 3.0 Stateless Session Beans
To build the domain tier for the application example, create a new Java project and name it AccountEJB. Again, remember to include the Java EE 5 library to the build path. To see the effectiveness of Spring injection in action, you will use a SLSB with a remote interface for this project. Create an interface class for a business implementation bean called ProfileManager as follows:

import javax.ejb.Remote; import com.app.domain.entity.Profile; @Remote public interface ProfileManager { public Profile getProfile(String id); public long setProfile(Profile p); }

This is nothing but a plain old Java interface (POJI) with an @Remote annotation added to indicate that you are going to create a remote interface for the SLSB.

Next, you create a POJO class that implements this interface and the methods in it. This is the class where you implement your business logic. After adding logic to the method, all you have to do is add an annotation (@Stateless) to make it an SLSB. You can use the optional element mappedName if you want the JNDI name to be different from the default. You can add it in the deployment descriptor or in the annotation as follows:

@Stateless(mappedName="ejb/ProfMgrEJB") public class ProfileManagerEJBImpl implements ProfileManager { ... }

Just by adding two annotations and no configuration, you have taken a simple POJO implementation class and non-intrusively transformed it into an EJB 3.0 stateless session bean. When deployed, the container will recognize the annotations and deploy the class in the EJB container with the appropriate default attributes, including the JNDI name--all without touching configuration files or creating Local, Home, and other classes.

If you are more comfortable with configuration files than with annotations, you can achieve the same result by adding the following to the ejb-jar.xml in the META-INF directory of the AccountEJB project:

<session> <ejb-name>ProfileManagerEJBImpl</ejb-name> <remote>com.app.domain.ejb.ProfileManager</remote> <mapped-name>ejb/ProfMgrEJB</mapped-name> <ejb-class>com.app.domain.ejb.impl.ProfileManagerEJBImpl</ejb-class> <session-type>Stateless</session-type> </session>

You successfully created the SLSB, but to use Spring in the EJB container you first need to create a separate application context file for the domain tier. This is necessary because the EJB is deployed in a separate container outside of the Web container and the EJB container will not recognize any context initialized in the web container. Also, creating a separate application context file is a good practice given the fact that you have separated your domain in a distinct project called AccountEJB because the context of domain should be independent of the presentation.

So create a new file called domainContext.xml under the project source directory. You will use the EJB deployment descriptor to initialize this context file. Also, create a new file ejb-jar.xml under the META-INF directory of the AccountEJB project, and add the following to initialize the Spring context in the domain tier:

<?xml version = '1.0' encoding = 'windows-1252'?> <ejb-jar version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_3_0.xsd"> <enterprise-beans> <session> <ejb-name>ProfileManagerEJBImpl</ejb-name> <remote>com.app.domain.ejb.ProfileManager</remote> <ejb-class>com.app.domain.ejb.impl.ProfileManagerEJBImpl</ejb-class> <session-type>Stateless</session-type> <env-entry> <env-entry-name>ejb/BeanFactoryPath</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>domainContext.xml</env-entry-value> </env-entry> </session> </enterprise-beans> </ejb-jar>

This code basically initializes the Spring context in the EJB tier as a environment variable for the SLSB using domainContext.xml.

To invoke beans instantiated by domainContext.xml from the POJO EJB class, extend a Spring helper class AbstractStatelessSessionBean and, using the onEjbCreate() method in the class, explicitly invoke the bean reference as follows:

public class ProfileManagerEJBImpl extends AbstractStatelessSessionBean implements ProfileManager { private ProfileDao profileDAO; public Profile getProfile(String id) { Profile pro = profileDAO.getProfile(id); return pro; } public long setProfile(Profile p) { return profileDAO.setProfile(p); } protected voID onEjbCreate() { profileDAO = (ProfileDao)getBeanFactory().getBean("profileDAO"); } }

The next section will elaborate on the bean profileDao while discussing domainContext.xml and the Spring context in an EJB container.

You use Spring in the domain tier not only to avail the usual benefits, but also to give yourself the option of implementing persistence using the JPA-compliant Hibernate tool (the next section shows how). You will use the EJB that you implemented as a POJO in EJB 3.0 to execute business logic and to persist data to the database using the EJB 3.0 ORM solution, JPA.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date