EJB 3.0 Database Persistence with Oracle Fusion Middleware 11g
上QQ阅读APP看书,第一时间看更新

Developing a session façade for an entity

In EJB 2.0, an entity bean is created with the create method in the home/local home interface and the entity bean fields are modified with the getter/setter methods in the local/remote interface. In EJB 3.0, an entity bean is created and modified with the EntityManager API. The EntityManager class provides methods for finding, persisting, and removing an entity bean instance. This section covers generation of a session bean that implements the EntityManager API.

In the session bean class, the EntityManager is obtained with the @Resource annotation:

@Resource private EntityManager em;

Some of the commonly used methods of the EntityManager class are listed in the following table:

EntityManager Metho           Description

persist(Object entity)           Saves an entity bean instance in the database. The persist method returns the entity bean that is persisted in the database.

find(String entityName, Object primaryKey)           Finds an entity bean instance with a primary key.

remove(Object entityBean)           Removes an entity bean from the database.

createQuery(String ejbQlString)           Creates an EJB QL query.

createNamedQuery(String queryName)           Creates a @NamedQuery query.

A stateless session bean class is annotated with the @Stateless annotation. In the session bean class, an entity bean is created with the create() method. For example, the create() method corresponding to the identifier property catalogId is as follows:

public void create(String catalogId)
{ CatalogBean catalogBean = new CatalogBean(catalogId);
em.persist(catalogBean);
}

The create() method is a custom method as opposed to the create() method of the EJB 2.0 specification; the method naming in the session bean façade may be modified. The persist() method of the EntityManager class saves a new entity in the database. The remove() method of the EntityManager class is used to remove an entity:

public void remove(CatalogBean catalogBean) {
em.remove(catalogBean);
}

The find() method of the EntityManager class is used to find an entity bean. In the session EJB, add finder methods for the named queries defined in the EJB bean class. The createNamedQuery() method is used to obtain a query object for a named query. For example, the finder method corresponding to the named query FindByCatalogId, which is defined in the entity class, is as follows:

public CatalogBean findByCatalogId(java.lang.String param1)
{Query query=em.createNamedQuery("FindByCatalogId");
query.setParameter(0, param1);
return (CatalogBean)(query.getSingleResult());
}

In the findByCatalogId() method, a javax.persistence.Query object is obtained from the named query FindByCatalogId. The parameter values are set on the query object. An entity EJB bean instance is obtained with the getSingleResult() method of the query object. The named query FindByCatalogId returns a single entity of the entity EJB bean. A named query may also return a collection of entities. For example, the named query FindByJournal returns a collection. The finder method corresponding to the FindByJournal named query is as follows.

public java.util.List<CatalogBean> findByJournal(java.lang.String param1)
{ Query query= em.createNamedQuery("FindByJournal");
query.setParameter(0, param1);
return query.getResultList();
}

In the findByJournal() method, a query object is obtained from the named query and a java.util.List of entity beans is obtained with the getResultList() method of the query object.

The XSLT stylesheet

The XSL stylesheet (façade-bean.xsl) used to generate the session bean façade class is listed below.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="ISO-8859-1" omit-xml-declaration="yes" method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="ejb-jar/enterprise-beans/entity"/>
</xsl:template>
<xsl:template match="package">
package
<xsl:value-of select="."/>;
</xsl:template>
<xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="ucletters">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:template match="entity">

Add the import statements:

import javax.persistence.EntityManager; import javax.persistence.Query; import
javax.annotation.Resource; import javax.ejb.Stateless;

Add the annotation to specify a Stateless bean:

<xsl:text disable-output-escaping="yes">@</xsl:text>
Stateless

Add the session bean class declaration:

<xsl:text> public class </xsl:text>
<xsl:value-of select="ejb-name"/>
FaçadeBean implements
<xsl:value-of select="ejb-name"/>
Façade{

Inject an EntityManager resource.

<xsl:text disable-output-escaping="yes">@Resource
</xsl:text>
<xsl:text>private EntityManager em;</xsl:text>

The create() method is used to create and persist an entity instance.

public void create(
<xsl:apply-templates select="cmp-field">
<xsl:with-param name="paramPK" select="'paramPK'"/>
<xsl:with-param name="primKeyField" select="primkey-field"/>
</xsl:apply-templates>
) {
<xsl:value-of select="ejb-class"/>
<xsl:text> </xsl:text>
<xsl:value-of select="translate((substring(ejb-class, 1,1)),$ucletters,$lcletters)"/>
<xsl:value-of select="substring(ejb-class,2)"/>
= new
<xsl:value-of select="ejb-class"/>
(
<xsl:apply-templates select="cmp-field">
<xsl:with-param name="pkField" select="'pkField'"/>
<xsl:with-param name="primKeyField" select="primkey-field"/>
</xsl:apply-templates>
); em.persist(
<xsl:value-of select="translate((substring(ejb-class, 1,1)),$ucletters,$lcletters)"/>
<xsl:value-of select="substring(ejb-class,2)"/>
); }

The remove() method is used to remove an entity instance.

public void remove(
<xsl:value-of select="ejb-class"/>
<xsl:text> </xsl:text>
<xsl:value-of select="translate((substring(ejb-class, 1,1)),$ucletters,$lcletters)"/>
<xsl:value-of select="substring(ejb-class,2)"/>
) { em.remove(
<xsl:value-of select="translate((substring(ejb-class, 1,1)),$ucletters,$lcletters)"/>
<xsl:value-of select="substring(ejb-class,2)"/>
); }
<xsl:apply-templates select="query"/>
}
</xsl:template>

Next, Create and use named query objects.

<xsl:template match="query">
<xsl:if test="collection-type">
public java.util.List
<xsl:text disable-output-escaping="yes">&lt;</xsl:text>
<xsl:value-of select="../ejb-class"/>
<xsl:text disable-output-escaping="yes">&gt; </xsl:text>
<xsl:value-of select="query-method/method-name"/>
(
<xsl:apply-templates select="query-method/method-params/method-param">
<xsl:with-param name="finderParam" select="'finderParam'"/>
</xsl:apply-templates>
){ Query query= em.createNamedQuery
<xsl:text disable-output-escaping="yes">("</xsl:text>
<xsl:value-of select="translate((substring(query-method/method-name, 1,1)),$lcletters,$ucletters)"/>
<xsl:value-of select="substring(query-method/method-name,2)"/>
<xsl:text disable-output-escaping="yes">")</xsl:text>
;
<xsl:apply-templates select="query-method/method-params/method-param">
<xsl:with-param name="queryParam" select="'queryParam'"/>
</xsl:apply-templates>
return query.getResultList(); }
</xsl:if>
<xsl:if test="not(collection-type)">
public
<xsl:value-of select="../ejb-class"/>
<xsl:text> </xsl:text>
<xsl:value-of select="query-method/method-name"/>
(
<xsl:apply-templates select="query-method/method-params/method-param">
<xsl:with-param name="finderParam" select="'finderParam'"/>
</xsl:apply-templates>
) { Query query=em.createNamedQuery
<xsl:text disable-output-escaping="yes">("</xsl:text>
<xsl:value-of select="translate((substring(query-method/method-name, 1,1)),$lcletters,$ucletters)"/>
<xsl:value-of select="substring(query-method/method-name,2)"/>
<xsl:text disable-output-escaping="yes">")</xsl:text>
;
<xsl:apply-templates select="query-method/method-params/method-param">
<xsl:with-param name="queryParam" select="'queryParam'"/>
</xsl:apply-templates>
return (
<xsl:value-of select="../ejb-class"/>
)(query.getSingleResult()); }
</xsl:if>
</xsl:template>
<xsl:template match="cmp-field">
<xsl:param name="paramPK"/>
<xsl:param name="pkField"/>
<xsl:param name="primKeyField"/>
<xsl:param name="fieldName" select="field-name"/>
<xsl:if test="$paramPK='paramPK'">
<xsl:if test="$primKeyField=$fieldName">
<xsl:value-of select="field-type"/>
<xsl:text> </xsl:text>
<xsl:value-of select="field-name"/>
</xsl:if>
</xsl:if>
<xsl:if test="$pkField='pkField'">
<xsl:if test="$primKeyField=$fieldName">
<xsl:value-of select="field-name"/>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="method-param">
<xsl:param name="finderParam"/>
<xsl:param name="queryParam"/>
<xsl:if test="$finderParam='finderParam'">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
param
<xsl:value-of select="position()"/>
<xsl:if test="position() != last()">,</xsl:if>
</xsl:if>
<xsl:if test="$queryParam='queryParam'">
query.setParameter(
<xsl:value-of select="position()-1"/>
param
<xsl:value-of select="position()"/>
);
</xsl:if>
</xsl:template>
<xsl:template match="text()">
<value-of select="." disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>

Generating the session Façade

Next, generate the EJB 3.0 session bean class that implements the EntityManager API with XSLT transformation. Set the input XML file and the output file in the Default Run Configuration as discussed earlier. Specify Input XML File as ejb-jar-modified.xml and Output File as CatalogFaçadeBean.java.

Generating the session Façade

Right-click on façade-bean.xsl and select Run.

Generating the session Façade

The CatalogFaçadeBean.java gets generated. Select View | Refresh to add the CatalogFaçadeBean.java class to the project. The EJB 3.0 session bean class implements the EJB 3.0 session bean remote interface CatalogFaçade. The session bean class generated is shown below:

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.annotation.Resource;
import javax.ejb.Stateless;
@Stateless
public class CatalogFaçadeBean implements CatalogFaçade{
@Resource
private EntityManager em;
public void create(String catalogId) {
CatalogBean catalogBean= new CatalogBean(catalogId);
em.persist(catalogBean); }
public void remove(CatalogBean catalogBean) {
em.remove(catalogBean); }
public CatalogBean findByCatalogId(java.lang.String param1) {
Query query=em.createNamedQuery("FindByCatalogId");
query.setParameter(0, param1);
return (CatalogBean)(query.getSingleResult()); }
public java.util.List <CatalogBean> findByJournal
(java.lang.String param1){ Query query= em.createNamedQuery("FindByJournal");
query.setParameter(0, param1 );
return query.getResultList(); }
}

We also need to generate an interface, CatalogFaçade.java, for the session bean class. The façade interface has the abstract method definitions for the methods implemented in the session bean façade. The XSLT stylesheet, façade.xslt, used to generate the session bean interface is listed next:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="ISO-8859-1" omit-xml-declaration="yes"
method="text" />
<xsl:template match="/">
<xsl:apply-templates select="ejb-jar/enterprise-beans/entity" />
</xsl:template>
<xsl:variable name="lcletters">
abcdefghijklmnopqrstuvwxyz
</xsl:variable>
<xsl:variable name="ucletters">
ABCDEFGHIJKLMNOPQRSTUVWXYZ
</xsl:variable>
<xsl:template match="entity">
import javax.ejb.Remote;
<xsl:text disable-output-escaping="yes">@</xsl:text>
Remote
<xsl:text> public interface </xsl:text>
<xsl:value-of select="ejb-name" />
Façade{ void create(
<xsl:apply-templates select="cmp-field">
<xsl:with-param name="paramPK" select="'paramPK'" />
<xsl:with-param name="primKeyField" select="primkey-field" />
</xsl:apply-templates>
); void remove(
<xsl:value-of select="ejb-class" />
<xsl:text> </xsl:text>
<xsl:value-of
select="translate((substring(ejb-class,
1,1)),$ucletters,$lcletters)" />
<xsl:value-of select="substring(ejb-class,2)" />
);
<xsl:apply-templates select="query" />
}
</xsl:template>
<xsl:template match="query">
<xsl:if test="collection-type">
java.util.List
<xsl:text disable-output-escaping="yes">&lt;</xsl:text>
<xsl:value-of select="../ejb-class" />
<xsl:text disable-output-escaping="yes">&gt; </xsl:text>
<xsl:text> </xsl:text>
<xsl:value-of select="query-method/method-name"/>
(
<xsl:apply-templates select="query-method/method-params/
method-param">
<xsl:with-param name="finderParam" select="'finderParam'"/>
</xsl:apply-templates>
);
<xsl:text disable-output-escaping="yes">
</xsl:text>
</xsl:if>
<xsl:if test="not(collection-type)">
<xsl:value-of select="../ejb-class"/>
<xsl:text> </xsl:text>
<xsl:value-of select="query-method/method-name"/>
(
<xsl:apply-templates select="query-method/method-params/
method-param">
<xsl:with-param name="finderParam" select="'finderParam'"/>
</xsl:apply-templates>
);
<xsl:text disable-output-escaping="yes">
</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="cmp-field">
<xsl:param name="primKeyField"/>
<xsl:param name="fieldName" select="field-name"/>
<xsl:param name="paramPK"/>
<xsl:param name="pkField"/>
<xsl:if test="$paramPK='paramPK'">
<xsl:if test="$primKeyField=$fieldName">
<xsl:value-of select="field-type"/>
<xsl:text> </xsl:text>
<xsl:value-of select="field-name"/>
</xsl:if>
</xsl:if>
<xsl:if test="$pkField='pkField'">
<xsl:if test="$primKeyField=$fieldName">
<xsl:value-of select="field-name"/>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="method-param">
<xsl:param name="finderParam"/>
<xsl:param name="queryParam"/>
<xsl:if test="$finderParam='finderParam'">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
param
<xsl:value-of select="position()"/>
<xsl:if test="position() != last()">,</xsl:if>
</xsl:if>
<xsl:if test="$queryParam='queryParam'">
query.setParameter(
<xsl:value-of select="position()"/>
, param
<xsl:value-of select="position()"/>
);
</xsl:if>
</xsl:template>
<xsl:template match="text()">
<value-of select="." disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>

Copy the façade.xsl to the EJB2toEJB3 project in JDeveloper. Set the Input XML File to ejb-jar-modified.xml and Output File to CatalogFaçade.java in the Default Run Configuration.

Generating the session Façade

Right-click on façade.xsl and select Run to transform the modified EJB 2.0 deployment descriptor to an EJB 3.0 session bean façade interface.

Generating the session Façade

The session bean façade interface CatalogFaçade.java gets generated. The @Remote annotation specifies a remote interface. CatalogFaçade.java is listed next:

import javax.ejb.Remote;
@Remote
public interface CatalogFaçade{
void create(String catalogId);
void remove(CatalogBean catalogBean);
CatalogBean findByCatalogId(java.lang.String param1 );
java.util.List <CatalogBean> findByJournal(java.lang.String param1);
}

Select View | Refresh to add the session bean interface to the EJB2toEJB3 conversion project. The session bean façade class and façade interface may require some reformatting.

Generating the session Façade