Resin 4 Java EE Application Server EJB Tutorial
From Resin 4.0 Wiki
Contents |
EJB Tutorials
Local Stateless Session Hello
Stateless sessions make database queries and updates robust by setting transaction boundaries at each business method. This stateless session bean example annotates a single business method with a SUPPORTS transaction attribute, marking the method as a read-only transaction boundary.
A Hello, World example for EJB 3.0 is much simpler than for earlier versions of EJB. To implement the EJB you need to implement:
- A local interface
- The bean implementation
To configure Resin to be a server for the EJB you need to:
- Configure the ejb-stateless-bean
- Inject the bean into the application servlet
In this tutorial, a simple "Hello" EJB is created and deployed within Resin.
Files in this tutorial
| File | Description |
|---|---|
WEB-INF/web.xml |
web.xml configuration |
WEB-INF/classes/example/Hello.java |
The local interface for the stateless session bean |
WEB-INF/classes/example/HelloBean.java |
The implementation for the stateless session bean |
WEB-INF/classes/example/HelloServlet.java |
The client for the stateless session bean |
Local Interface
The remote interface defines the client view of the bean.
It declares all the business methods. Our
only business method is the hello method.
Hello.java
package example;
public interface Hello {
public String hello();
}
Bean Implementation
The second class for EJBs is the bean implementation class. It implements the functionality provided by the remote interface.
HelloBean.java
package example;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import static javax.ejb.TransactionAttributeType.SUPPORTS;
import javax.inject.Named;
@Stateless
public class HelloBean implements Hello {
@Inject @Named("greeting")
private String _greeting;
@TransactionAttribute(SUPPORTS)
public String hello()
{
return _greeting;
}
}
@Stateless
The @Stateless annotation marks the bean as a stateless session
bean. Resin will create a stub implementing Hello and
store it in the Java Injection directory with type Hello and
name @Name("HelloBean").
The @Stateless annotation can have an optional name
value which overrides the default name of "HelloBean".
@Name
The @com.caucho.config.Name annotation tells Resin to lookup the
greeting String
in Java Injection directory using Resin's internal @Name binding "greeting" when the
session bean is created.
In this example, the greeting is configured with an <env-entry> in the web.xml.
Alternate Dependency Injection
In some cases, it may be clearer to configure the session bean directly, rather than using Java Injection injection. Instead of creating a separate <env-entry>, you can configure the greeting value using XML straight from the resin-web.xml file.
resin-web.xml
<web-app xmlns="http://caucho.com/ns/resin">
<qa:TestBean xmlns:qa="urn:java:qa">
<qa:greeting>Hello, World from web.xml</qa:greeting>
</qa:TestBean>
</web-app>
@TransactionAttribute
Managing transactions is the primary purpose of stateless
session beans. Transactions are a more powerful version of
a synchronized lock used to protect database integrity.
[doc|ejb-annotations.xtp#@TransactionAttribute @TransactionAttribute]
marks the transaction boundary for each business method.
==
@javax.ejb.TransactionAttribute(SUPPORTS) public String hello()
The hello() business method uses SUPPORTS because it's
a read-only method. It doesn't need to start a new transaction on its
own, but will participate in any transaction that already exists.
The REQUIRED transaction value starts up a new transaction if none already exists. It's used when updating database values.
| TransactionAttribute | meaning |
|---|---|
| REQUIRED | Start a new transaction if necessary |
| SUPPORTS | Don't start a new transaction, but use one if it exists |
Configuring the EJB stateless bean
<ee:Stateless> configure the session bean
from the resin-web.xml.
The <ee:Stateless> entry will
look at the bean's annotations to enhance the class.
ejb-stateless-bean in web.xml
<web-app xmlns="http://caucho.com/ns/resin"
xmlns:qa="urn:java:qa"
xmlns:lang="urn:java:java.lang"
xmlns:ee="urn:java:ee">
<lang:String ee:Named="greeting">
Hello, World
</lang:String>
<qa:TestBean>
<ee:Stateless/>
</qa:TestBean>
</web-app>
The <qa:TestBean> can optionally configure the bean directly with its properites as described in the alternate dependency injection section.
Client
HelloServlet.java
import javax.inject.Inject;
public class HelloServlet extends GenericServlet {
@Inject private Hello _hello;
public void service(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException
{
PrintWriter out = res.getWriter();
out.println(_hello.hello());
}
}
@EJB
The @Inject annotation tells
Resin to look for a Hello component in the Java Injection
repository.
The servlet could also lookup the Hello bean with JNDI in the
init() method or use an <init> configuration in the
web.xml:
alternative configuration
<web-app xmlns="http://caucho.com/ns/resin">
<servlet servlet-name="hello" servlet-class="example.HelloServlet">
<init hello="${Hello}"/>
</servlet>