Sie sind auf Seite 1von 14

EJB3

Struts

EJB 3
The EJB 3 provide an alternative to the CMP Entity
Beans to access the database.
Unlike the previous ones, they are synchronized with the
database only when decided by the program.

(See description in the WebLang page)

Book: D. Panda, R.Rahman, D Lane, “EJB3 in Action”,


Hamming.

1
Description in WebLang
ejb3 Country {
package myPackage;
relation <hasTowns 1:N isIn> Town;
String name;
int number;
public Country create(String name, int number);
public Country find(String name) {
query = "select c from Country c where c.name=?"
}
}

Use of an EJB3
javax.persistence.EntityManager em = ejb3_utility.Manager.open();
javax.persistence.EntityTransaction tx = em.getTransaction();
tx.begin();

Country c = Country.create("Switzerland", 1291);


c.setNumber(1291); // will appear in the DB at the latest at the commit

. . . Other calls to the EJBs in the same transaction . . .

tx.commit(); // or tx.rollback();
ejb3_utility.Manager.close();

2
Use of an EJB3
javax.persistence.EntityManager em = ejb3_utility.Manager.open();
javax.persistence.EntityTransaction tx = em.getTransaction();
tx.begin();
try {
country = Country.find("Switzerland");
} catch (javax.ejb.FinderException fe) {
country = Country.create("Switzerland");
}
tx.commit(); // or tx.rollback();
ejb3_utility.Manager.close();

Use of an EJB3

javax.persistence.EntityManager em = ejb3_utility.Manager.open();
javax.persistence.EntityTransaction tx = em.getTransaction();
tx.begin();
em.remove(country);
tx.commit(); // or tx.rollback();
ejb3_utility.Manager.close();

3
EJB3: Expression of relationships in WebLang
indication in Xxxx in Yyyy methods available in Xxxx
<hasY 1:1 hasX> Yyyy no relation Yyyy getHasY()
<hasX 1:1 hasY> Xxxx setHasY(yyyy)
<hasX 1:1 target hasY> (setHasY is made from the forward
Xxxx relationship name with first letter
capitalized)
<hasY 1:1 target hasX> no relation Yyyy getHasY()
Yyyy <hasX 1:1 hasY> Xxxx setHasY(yyyy)
<hasY 1:N hasX> Yyyy no relation java.util.Collection y = getHasY()
<hasX N:1 hasY> setHasY(collection)
addHasY(yyyy), removeHasY(yyyy)
<hasY N:M hasX> no relation java.util.Collection y = getHasY()
Yyyy <hasX N:M hasY> setHasY(collection)
Xxxx addHasY(yyyy), removeHasY(yyyy)

EJB3

Classes generated by WebLang

The files shown on the following


slides are generated by the
templates defined in the WebLang
environment

4
EJB3: support functions, manager
public class Manager { // ThreadLocal object, always the same
static private EntityManagerFactory emf = null;
private EntityManager em = null;
private static ThreadLocal<Manager> threadManager =
new ThreadLocal<Manager>() {
protected synchronized Manager initialValue() { … }
};
public static EntityManager open() { .. Next slide … }
public static void set(EntityManager em) { … }
public static void close() { … }
}

EJB3: the manager is created by a factory

public static EntityManager open() { // main manager method, always the same
Manager manager = (Manager) threadManager.get();
if (manager.em == null) {
if (Manager.emf == null)
Manager.emf = Persistence.createEntityManagerFactory("TestEJB3");
manager.em = manager.emf.createEntityManager();
manager.em.setFlushMode(FlushModeType.COMMIT);
}
return (manager.em);
}

5
EJB3: support functions, primary key

// In the EJB class


private long id;
@Id
@GeneratedValue
public long getId() {
return id;
}

public void setId(long id) {


this.id = id;
}

EJB3: support functions, creation


/**
* @generated // used by the merger, if it is called
*/
public static Country create(String name,int number) {
Country entity = new Country();
entity.name = name;
entity.number = number;
javax.persistence.EntityManager em = ejb3_utility.Manager.open();
em.persist(entity);
return (entity);
}

6
EJB3: support functions, finding them
/**
* @generated
*/
public static Country find(String name) throws Exception {
javax.persistence.EntityManager em = ejb3_utility.Manager.open();
Query query = em.createQuery("select c from Country c where c.name=?");
query.setParameter(1,name);
try {
Country result = (Country)query.getSingleResult();
return (result);
} catch (javax.persistence.NoResultException enf) {
throw new javax.ejb.FinderException(enf.getMessage());
} }

EJB3: support functions, relationships


@OneToMany(mappedBy="isIn")
public java.util.Collection<myPackage.Town> getHasTowns() {
return (hasTowns);
}
public void setHasTowns(java.util.Collection<myPackage.Town> hasTowns) {
if (hasTowns!=null) {
hasTowns.size(); // trick to avoid lazy initialisation
}
this.hasTowns = hasTowns;
}
public void addHasTowns(myPackage.Town town) {
if (this.hasTowns == null)
this.hasTowns = new java.util.ArrayList<myPackage.Town>();
this.hasTowns.add(town);
town._setIsIn(this); // sets the reverse link
}

7
EJB3: the EJB is disconnected from the
database between two calls

tx.begin();
client = Client.findByName("xxx");
tx.commit();

. . . presentation layer (Struts) . . .

tx.begin();
// x is reattached to the transaction
x = em.merge(client);

for (Bill b: client.getHasBills() {


x.addHasBills(em.merge(b));
}
tx.commit();

EJB3: lazy evaluation

tx.begin();
client = Client.findByName("xxx");
client.getHasBills().size(); // forces the collection to be loaded
// prevents the lazy evaluation
tx.commit();

// the collection may be handled outside the transaction


// provided the lazy evaluation has been thwarted

8
EJB3: reattaching the beans to the DB
tx.begin();

// reattach x to the transaction


x = em.merge(client);

// reintroduce the new copy into the session


request.getSession().setAttribute("client", x);

// attach the member of the collection


for (Bill b: client.getHasBills() {
x.addHasBills(em.merge(b));
}
tx.commit();

The EJB3 avoid the need of transferring data from


the persistent object to the servlet Java beans

9
JET: Java Emitter Templates
(Eclipse feature)
aaa = xxx
bbb = yyy1, yyy2
ccc = vvv
ddd = zzz

aaa xxx

bbb yyy1
ccc ddd yyy2
vvv zzz

JET
Java Emitter Templates

Support derived from the JSP compiler to


create templates in many different languages

WebLang page :
http://ltiwww.epfl.ch/WebLang/Modules.html#modulestdm

10
JET: Eclipse templates, variable part
<%@ jet
package="ch.epfl.lti.codegen.weblang.template.java.client.rmi"
imports="ch.epfl.lti.codegen.weblang.modules.java.client.rmi.*
ch.epfl.lti.codegen.weblang.modules.java.base.*"
class="GenRmiInterface“ %>

<% Rmi rmi = (Rmi)_argument[0];


String CLASSNAME = rmi.getNameFU(); %>

/* The interface of RMI method */


<% if (rmi.getPackage() != null) {%>
package <%=rmi.getPackage().toString() %>;
<% }%>
import java.rmi.Remote;

public interface <%=CLASSNAME%> extends Remote {


<% for (String signature : rmi.getMethodSignature()) {%>
public <%=signature%> throws Exception;
<% }%>
}

JET: Eclipse templates, constant part


<%@ jet
package="ch.epfl.lti.codegen.weblang.template.java.client.rmi"
imports="ch.epfl.lti.codegen.weblang.modules.java.client.rmi.*
ch.epfl.lti.codegen.weblang.modules.java.base.*"
class="GenRmiInterface"
skeleton="../generator.skeleton" %>

<% Rmi rmi = (Rmi)_argument[0];


String CLASSNAME = rmi.getNameFU(); %>

/* The interface of RMI method */


<% if (rmi.getPackage() != null) {%>
package <%=rmi.getPackage().toString() %>;
<% }%>
import java.rmi.Remote;

public interface <%=CLASSNAME%> extends Remote {


<% for (String signature : rmi.getMethodSignature()) {%>
public <%=signature%> throws Exception;
<% }%>
}

11
The templates defined in WebLang can
easily be modified by the developer
// Handled by a modified template
@templatedir = myEjb3
ejb3 Country extends strutsfsm.StateForm {
package myPackage;
relation <hasTowns 1:N isIn> Town;
String name;
int number;
public Country create(String name, int number);
public Country find(String name) {
query = "select c from Country c where c.name=?"
} }

WebLang
templates struts Supplier {
package store;
statemachine {
state state_0 > supply;
switch (sessionState) {
case state_s:
sessionState = state_0;
break;
case state_0:
...
}
@templatedir = zzzz
This page is handled
by an updated template page supply {
country (Enter) {}
country.hasTowns[] {}
}
}

12
Getting and compiling WebLang templates

Right-click the .cg file containing the @templatedir


Æ Get Templates Æ folder _cg_resources with
the templates corresponding to the module is created

Right-click the template you have modified Æ


Compile CG Template Æ a new project is
created to contain the templates (starts with “.” and is
thus not always visible)

Use of the modified templates

When you have compiled a template, it


will replace the standard one for all
subsequent compilations of the .cg file, as
long as you keep the @templatedir mark.

13
If you need extra parameters, you
may enter a block like this one

parameters {
xxxx = "aa ss" "bbb" ccc;
mainHtml = "/start/Lotery.jsp";
}

Use of the extra parameters


<% LinkedList sList = (LinkedList)_argument[0]; // within the html template

// sList is the list of parameters defined in the .cg file


DataTree root = (DataTree)_argument[1]; // root of the tree created by the parser
LinkedList aList = root.getMainInstancesOfClass(html.Html.class);
// available in every template
for (Object o : aList) { HashMap hm = ((html.Html)o).getParameters();
// one hash map per module
// with one key and one linkedList of String
// for each line of parameters
String name = ((html.Html)o).getName(); // get the name of the module
} %>

// html is the package and Html.class is the class. Also exist servlet.Servlet,
// struts.Struts
// See the WebLang page

14

Das könnte Ihnen auch gefallen