The Phone Book Bean Example
This is an example of a JSP-page calling an Enity Bean that uses annotations. The result looks like this:
Application Contents
First, let us take a look at the PhoneBook Entity Bean that represents a table in the database. Each instance of PhoneBook is a record of the table.
PhoneBook.java uses the
- @Entity annotation to mark this class as an Entity Bean
- @Table annotation to map the table name that is being represented by the Entity Bean.
- @Id annotation to specify the primary key of the table.
And, as usual their is an empty constructor for the Entity Bean
package org.apache.geronimo.samples.myphonebookpak; import java.io.Serializable; import javax.persistence.Id; import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table(name = "phonebook") public class PhoneBook implements Serializable { private String number; private String name; public PhoneBook() { } public PhoneBook(String name, String number) { this.name = name; this.number = number; } @Id public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } }
MyPhonebookLocal.java is the business interface that drives the above mentioned Entity Bean.
package org.apache.geronimo.samples.myphonebookpak; import org.apache.geronimo.samples.myphonebookpak.PhoneBook; public interface MyPhonebookLocal { public PhoneBook findByPrimaryKey(String name); }
MyPhonebookBean.java is where the implementation of the local (and if there is, a the remote) interface. To explain what the annotations in this Stateless Session Bean means I will enumerate them:
- @Stateless - tells Geronimo that this is a stateless session bean
- @PersistenceUnit - tells Geronimo to retrieve a persistence unit defined in the persistence.xml and place it in the EntityManagerFactory
Note that PersistenceContext is used when you are directly obtaining a EntityManager. For an EntityManagerFactory use PersistenceUnit.
package org.apache.geronimo.samples.myphonebookpak; import javax.ejb.Stateless; import javax.persistence.PersistenceUnit; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import org.apache.geronimo.samples.myphonebookpak.PhoneBook; @Stateless public class MyPhonebookBean implements MyPhonebookLocal { @PersistenceUnit(unitName="PhonePU") protected EntityManagerFactory emf; public MyPhonebookBean() { } public PhoneBook findByPrimaryKey(String name) { EntityManager em = emf.createEntityManager(); PhoneBook phonebook = (PhoneBook)em.find(PhoneBook.class, name); em.close(); return phonebook; } }
index.jsp is the JSP page that uses the EJB to access the database.
<%@ page contentType="text/html" import="org.apache.geronimo.samples.myphonebookpak.*, javax.naming.* " %> <% String searchName = ""; if (request.getParameter("searchname") != null) { searchName=request.getParameter("searchname"); } %> <html><head><title>Phonebook</title></head><body> <form action="index.jsp"> <b>Search number</b>:<br> Enter name: <input type="text" name="searchname" value="<%=searchName%>"> <input type="submit" value="Search"> (Test with <a href="index.jsp?searchname=Mattias">Mattias</a>) </form> <% if (! searchName.equals("")) { String number=""; try { Context context = new InitialContext(); MyPhonebookLocal myPhonebookLocal = (MyPhonebookLocal)context.lookup("java:comp/env/ejb/MyPhonebookBean"); PhoneBook phonebook = myPhonebookLocal.findByPrimaryKey(searchName); if(phonebook != null) { number = phonebook.getNumber(); } } catch (Exception e) { number=e.toString(); } out.println("This is the number returned from the EJB when searching for '"+searchName+"' : " + number); } %> </body></html>
Deployment Plans for EJB
openejb-jar.xml just specifies the module's information.
<?xml version="1.0" encoding="UTF-8"?> <openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.1" xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.1" xmlns:pkgen="http://www.openejb.org/xml/ns/pkgen-2.0" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.1" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.2"> <sys:environment> <sys:moduleId> <sys:groupId>org.apache.geronimo.samples</sys:groupId> <sys:artifactId>MyPhonebookBean</sys:artifactId> <sys:version>1.0</sys:version> <sys:type>car</sys:type> </sys:moduleId> </sys:environment> </openejb-jar>
persistence.xml will specify the name of the PersistenceUnit. This name is used when referencing for the EntityManagerFactory. I have denoted it as PhonePU. For some reason I could not get it to reference with jta-data-source. So the alternative method is to explicitly specify the ConnectionURL, ConnectionDriverName, and ConnectionUserName. I added an extra property called SynchronizeMappings so that the data in the database will not be overwritten.
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="PhonePU"> <description>Phone Book</description> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <class>org.apache.geronimo.samples.myphonebookpak.PhoneBook</class> <properties> <property name="openjpa.ConnectionURL" value="jdbc:derby:PhoneBookDB" /> <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver" /> <property name="ConnectionUserName" value="app" /> <property name="openjpa.jdbc.SynchronizeMappings" value="false" /> </properties> </persistence-unit> <!-- <jta-data-source>PhoneBookPool</jta-data-source> <non-jta-data-source>PhoneBookPool</non-jta-data-source> --> </persistence>