An introduction to EJB standard 3.0, part of Java Enterprise Edition. EJB contains features that are necessary when dealing with enterprise software. In particular, when considering also economic aspects like ROI and so forth.
1. AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Introduction to Enterprise
JavaBeans
Pasquale Imbemba, 9.4
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Ripartizione 9 - InformaticaAbteilung 9 - Informationstechnik
Amt 9.4 – Amt für technisch-wirtschaftliche Informatik Ufficio 9.4 – Informatica tecnica-economica
2. Introduction to Enterprise JavaBeans 2
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Contents
● What they teach you at school
● Naming and legacy
● The need for distributed components
● Consequences
● Enterprise JavaBeans
● Session Beans
● Entity Beans
– Relationships
– Entity Manager
● Persistence Unit and Persistence Context
● Interface
3. Introduction to Enterprise JavaBeans 3
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Contents
● Message Driven Beans
● A use case
● Advanced Entity Beans
● Secondary Table
● Inheritance strategies
● Timer Service
● Bibliography
4. Introduction to Enterprise JavaBeans 4
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
What they teach you at school
● Code reuse improves code stability
● Less error prone
– Bugs deminish because code usage increases
● Avoid redundancy
– Don't rewrite what's already done
● Lower error risk
– Eventually help to improve existing code
● Don't begin from scratch
– Build on more and more consolidated code
5. Introduction to Enterprise JavaBeans 5
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Naming and legacy
● Before 3.0, ejb were clumsy and complex
● You were obliged to implement interfaces needed by
the very same architecture
● Rod Johnson writes J2EE development without EJB,
releases first version of Spring Framework (2002)
● EJB 2.x = J2EE
● EJB 3.0 = Java EE 5, 3.1 = EE 6
● „Java EE 6 Gets it Right“, Rod Johnson's blog at
http://blog.springsource.com/2007/07/03/java-ee-6-
gets-it-right/
6. Introduction to Enterprise JavaBeans 6
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Distributed Application Frameworks
● DCOM, COM+, WCF (Microsoft)
● http://msdn.microsoft.com/de-
de/netframework/aa663324.aspx
● Enterprise JavaBeans (Java)
● this presentation :)
● http://java.sun.com/products/ejb/
● CORBA (Object Management Group)
● a specification, not tied to a specific language
● use IDL and language binding
● http://www.omg.org/cgi-bin/doc?formal/04-03-12.pdf
7. Introduction to Enterprise JavaBeans 7
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
The need for distributed
components
type
myApp = class;
procedure ...
begin
//do smthg very difficult
end
public partial class MyOwnApp
public Object myOwnComplexSolution(){
Object o = Helper.getMyComplexSolution;
. . .
}
public class MyApp
public Object myComplexSolution() {
//do smthg very difficult
return Object;
public class MyVerySpecialApp
public void computeSmthg(){
Object o = MyApp.myComplexSolution() {
}
8. Introduction to Enterprise JavaBeans 8
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Solutions
● Copy and paste the
algorithm
● (Re)write the
algorithm
● Delegate the
algorithm to the
business expert dev
team and make it
available
Many solutions = many
maintainers
Which is the right solution?
Make algorithm available
cross platform
9. Introduction to Enterprise JavaBeans 9
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Solution
public partial class MyOwnApp
public Object myOwnComplexSolution(){
Object o = WS.myComplexSolution;
. . .
}
public class MyVerySpecialApp{
public void computeSmthg(){
//look up for bean
//consume method
}
}
Java EE 5
AS
public class MyApp{
public Object myComplexSolution() {
//do smthg very difficult
return Object;
}
}
Bean
type
myApp = class;
procedure ...
begin
//do smthg very difficult
end
Webservice
db
10. Introduction to Enterprise JavaBeans 10
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Improvements
● By delegating to the business expert → You
obtain a business data asset
● No redundacy
● Data is expect to be as correct as possible
– Consistent / semantic: data makes sense, it means
smthg, because it is from the business expert domain
● Example: …
Complete:
11. Introduction to Enterprise JavaBeans 11
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Solution's algorithm (~)
1) Define a remote interface
2) Write a Java class that implements that interface
● Make proper annotations (e.g. @Stateless …)
● May require entity beans, goto 2)
3) Test
4) Define an endpoint interface
● (you may use inheritance :) )
● Make the proper annotations (e.g.@Webmethod)
5) Deploy
12. Introduction to Enterprise JavaBeans 12
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
The need for distributed
components
Application A Application BApplication C
13. Introduction to Enterprise JavaBeans 13
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
A possible (re) use case
GCA
BDPA
1 .queries for person
2. returns person
XMas
3.stores
4. change in person
4a.update
4b. inform
4c. update
4d. synch with Data
responsability
14. Introduction to Enterprise JavaBeans 14
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
A possible (re) use case
GCA
BDPA
1. queries for person
2. returns UUID
EFIN
Schema
3.stores
4. change
in person
5. updates
Data
responsability
Component
responsability
AU
15. Introduction to Enterprise JavaBeans 15
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Consequences
● The semantic meaning of the database may
change
● from health serviced people into general people
– Although in our case, people derived from GCA are
probably a subset of health serviced people
● The type of responsability changes
● from data responsability to component
responsability
● data quality now is a cross office issue!
16. Introduction to Enterprise JavaBeans 16
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Why we need 3 tier architecture
Monolithic
Client
(Database)
Server
UI
Business Services
Data Services
17. Introduction to Enterprise JavaBeans 17
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Why we need 3 tier architecture
● Decoupling UI logic from business logic
● Other components may use the logic as part of their process
● Change business logic only in one place
● 'Slims' the client
● By isolating business logic, many types of UI can use it
● Decoupling business logic from persistence logic
● Makes data services exchangeable
● Expose business logic as webservice makes it available
cross platform
● No doubt: it's more complex to write applications
18. Introduction to Enterprise JavaBeans 18
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Why we need 3 tier architecture
Business Services
Data Services
Business Services
Fat Client UI Webservice
Business Services
Mobile UI Web UI
19. Introduction to Enterprise JavaBeans 19
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Consequences
● Develop components instead of spot solutions
● Java development should use EJB 3.0 architecture
– Develop beans that implement a remote interface
– Make methods/beans cross-platform implementing a endpoint
interface (→ Webservice)
– TODO: must find UI framework, Seam would be a candidate
● .NET development uses CEE.NET framework
– Complete of Enterprise and UI Tier, many improvements wrt
Java CEE
● Delphi
– ?
20. Introduction to Enterprise JavaBeans 20
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Enterprise JavaBeans
EJB
Entity Beans
Message-Driven
Beans
Session Beans
Stateful Stateless
21. Introduction to Enterprise JavaBeans 21
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Session Beans
● Contain business logic (algorithms)
● Some of these methods should be made „public“
– for clients on other JVM: must be „remotable“
– for clients on the same JVM: can be „locable“
● Clients use Java Naming and Directory Interface (JNDI) to
lookup bean
● Stateless:
● Solutions in „one shot“ → give parameter, get result
● Bean doesn't know about the client
● Stateful:
● Solution needs multiple steps → see shopping cart example
● Bean knows about the client (state)
22. Introduction to Enterprise JavaBeans 22
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Session Bean example
package it.bz.provinz.server.i;
import javax.ejb.Remote;
@Remote
public interface CFRemote{
public boolean isValid(String cf);
}
package it.bz.provinz.server.l;
import it.bz.provinz.server.i.CFRemote;
@Stateless
public class CheckerBean implements CFRemote{
public boolean isValid(String cf){
...
}
Java Clients must know about the interface
if they are to use remote / local interface
23. Introduction to Enterprise JavaBeans 23
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Entity Beans
● Just normal Java class that maps to a table
● But there's more to it on an advanced level :)
ID_PER NAME SURNAME DOB CF
1 Pasquale Imbemba 19.06.1970 MBMPQL70H19Z112A
2 Joe Pillow 02.05.1984 ...
3 ... ... ...
package it.bz.provinz.server.e;
import javax.persistence.*;
@Entity
@NamedQueries({@NamedQuery(name=“Person.findByCF“,
query = „SELECT p FROM Person p WHERE p.codiceFiscale
=:cf“)})
@Table(name=“PERSON“)
public class Person implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@Column(name=“ID_PER“)
private int id;
@Column(name=“NAME“)
private String name;
@Column(name=“SURNAME“)
private String surname;
@Column(name=“DOB“)
private Date dOb;
@Column(name=“CF“)
private String codiceFiscale;
Query logic is delegated to entity bean
We use EJB QL
24. Introduction to Enterprise JavaBeans 24
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Entity Beans
import javax.persistence.*;
@Stateless
public class CheckerBean implements CFRemote
@PersistenceContext(unitName =“JavaEE“)
private EntityManager eManager;
public boolean isValid(String cf){
Query q = eManager.createNamedQuery(„Person.findByCF“);
q.setParameter(„cf“, cf);
if (q.getResultList().size() > 0)
return true;
return false;
}
We use the query defined in the
entity bean
We use the annotation
@PersistenceContext
to inject a reference to EntityManager
References a deployment descriptor
(persistence.xml) in META-INF. This is the
persistence unit name
25. Introduction to Enterprise JavaBeans 25
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Relationships: OneToOne
…
ADDID (FK)
PERSON
ID
STREET
ZIP
TOWN
COUNTRY
ADDRESS
@Entity
@Table(name=“PERSON“)
public class Person {
…
@OneToOne
@JoinColumn(name=“ADD_ID“)
private Address adr;
…
26. Introduction to Enterprise JavaBeans 26
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Relationships: @OneToOne
PERID (PK)
...
PERSON
@Entity
@Table(name=“PERSON“)
public class Person {
…
@OneToOne
@PrimaryKeyJoinColumn
private Address adr;
…
PERID (PK)
STREET
ZIP
TOWN
COUNTRY
ADDRESS
27. Introduction to Enterprise JavaBeans 27
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Relationships: @OneToOne
● mappedBy
● when we want to express a mutual relationship, i.e.
– a person might have at most one address, and an
address belongs exactly to one person
– one of the two entities is the relationship owner (the one
that has the FK)
– the other refers to the relationship owner
@Entity
@Table(name=“PERSON“)
public class Person {
…
@OneToOne(mappedBy=“per“)
private Address adr;
…
@Entity
@Table(name=“ADDRESS“)
public class Address {
…
@OneToOne
@PrimaryKeyJoinColumn
private Person per;
…
28. Introduction to Enterprise JavaBeans 28
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Relationships: @OneToMany
ORDID (PK)
PERID (FK)
...
ORDER
ARTID (PK)
ORDID (PK)
QUANT
PRICE
ORDERPOS
@Entity
@Table(name=“ORDER“)
public class Order {
…
@OneToMany
@JoinColumn(name=“ORDID“)
private Collection<OrderPos> orderPos = new ArrayList<OrderPos>;
…
Refers to the column of ORDERPOS
java.util.List, java.util.Map,
or java.util.Set may be used
29. Introduction to Enterprise JavaBeans 29
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Relationship: @ManyToOne
ORDID (PK)
PERID (FK)
...
ORDER
PERID (PK)
...
PERSON
@Entity
@Table(name=“ORDER“)
public class Order {
…
@ManyToOne
@JoinColumn(name=“PERID“)
private Person person;
…
again, if the relationship is mutual...
@Entity
@Table(name=“PERSON“)
public class Person {
…
@OneToMany(mappedBy=“person“)
private Collection<Order> orders = new ArrayList<Order>();
30. Introduction to Enterprise JavaBeans 30
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Relationship
● @ManyToMany
● FetchType.EAGER and FetchType.LAZY
● CascadeType
● is optional, if set should be coherent with RI on db
side
31. Introduction to Enterprise JavaBeans 31
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Entity Beans
● Managed
● EntityManager
monitors the object =
entity bean
● Any change can lead
to a database action
● Unmanaged
● Just Java objects
32. Introduction to Enterprise JavaBeans 32
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
EntityManager
● Some history:
● Prior to 3.0, the definition of the peristence layer was
part of the EJB-specification
● Now, it's part of Java Persistence API 1.0 (in 3.0) – JPA
– that's where the EntityManager comes in
● Entity beans are just Java classes that contain
meta information (annotations) with which the EM
keeps aligned their attributes with the database
● Alignment occurs only when Entity Bean is assigned to
the EntityManger
– We say that Bean is „managed“
33. Introduction to Enterprise JavaBeans 33
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
EntityManager
● When the bean is managed, the EntityManager
will observe any attribute changes and decides,
within the transaction, of the necessary steps to
keep these changes aligned with the database
● All entity beans and all relative changes
managed by the EntityManager, are part of the
so called PersistenceContext, which is typically
(but not necessarily) tied to a transaction
34. Introduction to Enterprise JavaBeans 34
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
EntityManager
● To work with EM, we must define the scope of
the persistence unit with a deployment
descriptor (persistence.xml)
● Each persistence unit is connected to a data
source
<?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"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="JavaEE" transaction-type=“JTA“>
<jta-data-source>java:DefaultDS</jta-data-source>
</persistence-unit>
<persistence-unit name=“AGRO“ transcation-type=“JTA“>
<!--provider: we use standard :) →
<jta-data-source>jdbc:AgroDS</jta-data-source>
</persistence-unit>
</persistence>
Deployment descriptor
JTA: transaction is
managed by AS
(way to go in Java EE) or
<non-jta-data-source>
(Java SE)
35. Introduction to Enterprise JavaBeans 35
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
EntityManager Interface
● persist()
● takes the entity bean as argument, EM monitors now. The very moment in which EM writes
to db depends on the FlushMode. To force the insert, flush() can be used after
persist(). This forces EM to synchronize the persistence context with the database
● find() and getReference()
● Two methods to retrieve an entity bean by its PK. Both expect the EB's class and a reference
to the PK. While find() may return null, getReference() may result into a
EntityNotFoundException
● createQuery(), createNamedQuery, and createNativeQuery()
● for queries other than by PK using EJB QL. From an architectual point of view, queries
should always be defined inside the entity bean (@NamedQuery). If it is necessary to query
tables that don't have entity beans mapped to, it's still possibile to use SQL
36. Introduction to Enterprise JavaBeans 36
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
EntityManager Interface
● merge()
● if the bean doesn't belong to a persistence context, it is possible to
synchronize its changes by using the merge() method, which verifies if
there's already a record with the relative PK: if so, it will update all fields of
the record with the attributes of the bean, otherwise it will insert a new record
● remove()
● deletes a bean instance within transaction scope. Just as with persist(), it
is possibile to use flush() to force the real moment of deletion. The entity
bean as such ceases to exist, further changes made to it after the invocation
are not monitored.
● lock()
● takes two parameters, bean instance and LockModeType (READ or WRITE).
WRITE will increment the version number (if the entity bean disposes of
@Version)
37. Introduction to Enterprise JavaBeans 37
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
EntityManager Interface
● refresh()
● updates the current attributes of the entity bean with values from database, i.e. all
attribute changes which were not persisted are lost.
● contains() and clear()
● The first informs if a bean instance is monitored by an EntityManager (resulting in
true or false). The latter stops the EntityManager from monitoring all of its beans
– if you didn't flush(), all changes are lost
● flush() and setFlushMode()
● persist(), merge(), and remove() are not applied instantly, flush() can be
used to do so. Shall it be used? Depends on
● FlushModeType (AUTO is default)
– AUTO: EM decides when to access db. flush() does make sense here only if you're doing
mass changes (UPDATE / DELETE)
– COMMIT: All changes are executed only at the end of the transaction. This boosts database
performance, but the developer must be aware of what he's doing, otherwise performance is lost
if flush() is applied too many times
38. Introduction to Enterprise JavaBeans 38
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
EntityManager Interface
● getDelegate()
● Access to the concrete, vendor-specific
implementation of the EM
● Know what you're doing: leaving the standard...
39. Introduction to Enterprise JavaBeans 39
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
PersistenceContext
● It's the sum of Entity Beans that are managed by an Entity Manager
● At application runtime there can be many such contexts, since they're
usually tied to transactions
●
When calling methods, every user gets his own Persistence Context. Entity
Beans contained in the context may be equal or different and the context
develops as the user proceeds with the application. When reaching
transaction's end, at the latest, the EntityManager will try to map the actual
situation to the database by generating SQL instructions. This may rise
errors in case it doesn't succeed.
● Each Persistence Context concurrs against another
40. Introduction to Enterprise JavaBeans 40
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Transactionoriented
PersistenceContext
@Stateful
public class FooBean implements FooBeanRemote{
@PersistenceContext(unitName=“JavaEE“)
private EntityManager manager;
private Item item;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Item getItem(int itemNo) throws ItemException {
item = manager.find(Item.class, itemNo);
if (item == null)
throw new ItemException(„Could not find item“);
item.setQuant(item.getQuant()-1);
return item;
}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void changeItem(Item aNewItem) throws ItemException {
item.setName(aNewItem.getName());
item.setQuant(aNewItem.getQuant());
item.setPrice(aNewItem.getPrice());
manager.merge(item);
}
}
managed
managed
The transactionoriented Persistence Context lives as long as the transaction
and will be closed upon transaction closure. Prior to this, any changes occurred
must be synchronized with the database, before turning entity beans into normal
objects again.
41. Introduction to Enterprise JavaBeans 41
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Extended transactionoriented
Persistence Context
● It's possibile to extend the persistence context over
the end of a transaction
● Its lifecycle is therefore tied to the lifecycle of the
stateful session bean
● Only stateful session beans are allowed to define an
extended persistence context
● All Entity Beans that the client has been dealing with
remain under the control of the EntityManager
● provided that the context survives the end of the transaction
42. Introduction to Enterprise JavaBeans 42
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Extended transactionoriented
PersistenceContext
@Stateful
public class FooBean implements FooBeanRemote{
@PersistenceContext(unitName=“JavaEE“,type=“PersistenceContextType.
EXTENDED)
private EntityManager manager;
private Item item;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Item getItem(int itemNo) throws ItemException {
item = manager.find(Item.class, itemNo);
if (item == null)
throw new ItemException(„Could not find item“);
item.setQuant(item.getQuant()-1);
return item;
}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void changeItem(Item aNewItem) throws ItemException {
item.setName(aNewItem.getName());
item.setQuant(aNewItem.getQuant());
item.setPrice(aNewItem.getPrice());
}
}
managed
43. Introduction to Enterprise JavaBeans 43
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Message Driven Beans
● Asynchronous
● Decoupled from client
● Execute things at a later time
● Listen (subscribe) to a queue or a topic
● Topic: „broadcast“, message is delivered to all
● Queue: message is delivered only to first requesting MDB
● Do not contain business methods
● Doesn't know about remote / local
● Must implement onMessage() interface
● Transaction safe from sending to delivering
● Depends on which Java Messaging Service (JMS) is used
44. Introduction to Enterprise JavaBeans 44
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
MDB Schematics
Client
Channel
Sends a message
Message Driven
BeanMessage Driven
Bean
MDB
Message Driven
Bean
Listen to channel
onMessage(Message m)
{
doSmthg using m
}
45. Introduction to Enterprise JavaBeans 45
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
MDB use case
● Every new inscription of a farmer is an event
we want to react to
● One reaction is to print a welcome letter to be
signed by the member of our provincial
government (Landesrat)
● There could be several others of which we
actually don't know!
● Note that we extract added value out of this
business event
46. Introduction to Enterprise JavaBeans 46
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
MDB Use Case
InscriptionBean
Topic agrar
„Inscription“, Farmer
Message Driven
BeanMessage Driven
Bean
MDBWelcomeMDBean
Listen to topic
onMessage(Message m)
{
invoke WelcomeLetterBean
with data contained in
m
}
WelcomeLetterBean
47. Introduction to Enterprise JavaBeans 47
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Inscription Bean
import javax.annotation.Resource;
import javax.ejb.*;
import javax.jms.*;
@Stateless
public class InscriptionBean implements InsRemote{
@PersistenceContext(unitName =“JavaEE“)
private EntityManager eManager;
@Resource(mappedName=“ConnectionFactory“)
private ConnectionFactory factory;
@Resource(mappedName=“topic/agrar“
private Topic topic;
public boolean inscribe(Farmer f){
...
if (factory != null && topic != null){
Connection connect = factory.createConnection();
Session session = connect.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer sender = session.createProducer(topic);
ObjectMessage msg = session.createObjectMessage();
msg.setObject(f);
msg.setStringProperty(„MessageFormat“, „Inscription“);
sender.send(msg);
connect.close();
}
}
}
We can pass any serializable object.
We can send Text-, Map-,
Stream-, Byte-, and ObjectMessages
48. Introduction to Enterprise JavaBeans 48
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
WelcomeMDBean
import javax.annotation.Resource;
import javax.ejb.*;
import javax.jms.*;
@MessageDriven(activationConfig={
@ActivationConfigProperty(
propertyName=“destinationType“,
propertyValue=“javax.jms.Topic“),
@ActivationConfigProperty(
propertyName=“destination“,
propertyValue=“topic/agrar“),
@ActivationConfigProperty(
propertyName=“messageSelector“,
propertyName=“MessageFormat = 'Inscription'“)
@ActivationConfigProperty(
propertyName=“acknowledgeMode“,
propertyValue=“Auto-acknowledge“)})
public class WelcomeMDBean implements MessageListener {
public void onMessage(Message message){
try {
ObjectMessage oM = (ObjectMessage) message;
Object o = oM.getObject();
if (o != null){
Farmer f = (Farmer)o;
// instantiate WelcomeLetterBean and pass object
...
}
}
We react only to this message format
49. Introduction to Enterprise JavaBeans 49
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Advanced entity beans
● Real life database scenario:
● You aren't able to map entity beans top-down 1:1, i.e. from
bean to table because a db already exists
● Solutions
– redesign database (but many other applications use that db, so what?)
– map existing tables bottom-up, 1:1 into entities (you capitulate quickly)
● The „new“ Java EE standard allows extending attributes
over several tables
● Ideally, the application developer doesn't know about the
database structure, because he/she deals just with objects
50. Introduction to Enterprise JavaBeans 50
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
@SecondaryTable
● (easy) Case: We have a 1:1 relation between
two tables, namely person and address
● We want to deal only with one entity bean, say
SuperPerson, that contains a person with
his/her address
ID_PER NAME SURNAME DOB CF
ID_PER TYPE STREET ZIP TOWN
51. Introduction to Enterprise JavaBeans 51
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
SuperPerson entity bean
package it.bz.provinz.server.e;
import javax.persistence.*;
@Entity
@NamedQueries({@NamedQuery(name=“SuperPerson.findByCF“, query = „SELECT p FROM SuperPerson p
WHERE p.codiceFiscale =:cf“)})
@Table(name=“PERSON“)
@SecondaryTable(name=“ADDRESS“)
public class SuperPerson implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@Column(name=“ID_PER“)
private int id;
@Column(name=“NAME“)
private String name;
@Column(name=“SURNAME“)
private String surname;
@Column(name=“DOB“)
private Date dOb;
@Column(name=“CF“)
private String codiceFiscale;
@Column(name=“TYPE“, table=“ADDRESS“)
private String type;
@Column(name=“STREET“, table=“ADDRESS“)
private String street;
@Column(name=“ZIP“, table=“ADDRESS“)
private String zip;
@Column(name=“TOWN“, table=“ADDRESS“)
private String town;
//getter and setter methods
52. Introduction to Enterprise JavaBeans 52
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
@Inheritance
● It's possible to construct inheritance hierarchies
that the EntityManager can deal with
● InheritanceTypes in a glimpse:
– SINGLE_TABLE
● You deal with specialized objects, but have one table (and a
column for object type information)
– TABLE_PER_CLASS
● A table for every class, repeating all attributes on hierarchy depth
– JOINED
● A table for every class, but it contains only the PK and the
attributes handled by the relative class
53. Introduction to Enterprise JavaBeans 53
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Inheritance use case
Geldkarte
MitLimit
Auslandskarte
● Geldkarte
● Can handle credit
(Guthaben)
● MitLimit
● additionally handles a
top limit
● Auslandskarte
● Additionally handles
countries (for which
we can have different
limits)
54. Introduction to Enterprise JavaBeans 54
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Without annotations
public class Geldkarte{
private int nr;
private BigDecimal guthaben;
public int getNr(){
return nr;
}
public void setNr(int nr){
this.nr=nr;
}
public BigDecimal getGuthaben(){
return guthaben;
}
public void setGuthaben(BigDecimal guthaben){
this.guthaben = guthaben;
}
} public class MitLimit extends Geldkarte{
private BigDecimal limit;
public BigDecimal getLimit(){
return limit;
}
public void setLimit(BigDecimal limit){
this.limit = limit;
}
} public class Auslandskarte extends MitLimit{
private String land;
public String getLand(){
return land;
}
public void setCountry(String land){
this.land = land;
}
}
Our task: tell the entityManager
how relative data is organized
It's just basic Java :)
55. Introduction to Enterprise JavaBeans 55
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
SINGLE_TABLE
CREATE TABLE GELDKARTE_ALL
(
NR INTEGER NOT NULL PRIMARY KEY,
GUTHABEN DECIMAL(7,2) NOT NULL,
LIMIT DECIMAL(7,2),
LAND CHAR(30),
OBJ_TYP VARCHAR(31)
);
...
@Entity
@Table(name = "GELDKARTE_ALL")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="OBJ_TYP",discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue("Geldkarte")
public class GeldkarteSC {
@Id
@SequenceGenerator(name = "Kartennummern", sequenceName = "GeldkarteSeq",
initialValue = 1, allocationSize = 50)
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="Kartennummern")
@Column(name = "NR")
private int nr;
@Column(name = "GUTHABEN")
private BigDecimal guthaben;
// getter and setter methods
}
We must store information about the object type
56. Introduction to Enterprise JavaBeans 56
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
SINGLE_TABLE
...
@Entity
@DiscriminatorValue("Mit Limit")
@NamedQueries({@NamedQuery(name = "MitLimitSC.findAll", query = "SELECT o FROM
MitLimitSC o ORDER BY nr") })
public class MitLimitSC extends GeldkarteSC {
@Column(name = "LIMIT")
private BigDecimal limit;
public BigDecimal getLimit() {
return limit;
}
public void setLimit(BigDecimal limit) {
this.limit = limit;
}
}
...
@Entity
@DiscriminatorValue("Auslandskarte")
public class AuslandskarteSC extends MitLimitSC {
private String land;
@Column(name = "LAND")
public String getLand() {
return land;
}
public void setLand(String land) {
this.land = land;
}
}
Q: If we persist 2 MitLimitSC
and 1 AuslandskarteSC,
How many items would
„MitLimitSC.findAll“ return?
57. Introduction to Enterprise JavaBeans 57
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
SINGLE_TABLE
● means:
● One physical table that contains all possibile class
shapes (base and specialized classes)
– fields of the specialized classes must be nullable
columns on the table
● is the default type if no InheritanceType is set
● Next: Table-Per-Class
58. Introduction to Enterprise JavaBeans 58
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
TABLE_PER_CLASS
● means: one table per class
● We don't save object type info anymore
● The table of the base class consists of all
attributes of the related EntityBean
● The table of an inherited class consists of all
attributes of the base class plus those of its
own
● Result: the more complex the hierarchy, the
longer the table structure
59. Introduction to Enterprise JavaBeans 59
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
TABLE_PER_CLASS
CREATE TABLE GELDKARTE
(
NR INTEGER NOT NULL PRIMARY KEY,
GUTHABEN DECIMAL(7,2) NOT NULL
);
CREATE TABLE MIT_LIMIT_ALL
(
NR INTEGER NOT NULL PRIMARY KEY,
GUTHABEN DECIMAL(7,2) NOT NULL,
LIMIT DECIMAL(7,2) NOT NULL
);
CREATE TABLE AUSLANDSKARTE_ALL
(
NR INTEGER NOT NULL PRIMARY KEY,
GUTHABEN DECIMAL(7,2) NOT NULL,
LIMIT DECIMAL(7,2) NOT NULL,
LAND CHAR(30) NOT NULL
);
...
@Entity
@Table(name = "GELDKARTE")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class GeldkarteTCC {
private int nr;
private BigDecimal guthaben;
...
}
...
@Entity
@NamedQueries( { @NamedQuery(name = "MitLimitTCC.findAll",
query = "SELECT o FROM MitLimitTCC o") })
@Table(name = "MIT_LIMIT_ALL")
public class MitLimitTCC extends GeldkarteTCC {
private BigDecimal limit;
...
}
...
@Entity
@Table(name = "AUSLANDSKARTE_ALL")
public class AuslandskarteTCC extends MitLimitTCC {
private String land;
...
}
60. Introduction to Enterprise JavaBeans 60
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
JOINED
● Again we have three tables
● But these contain only the primary key and those
attributes, that are managed by the relative class
● Data must be collected from different tables
● Less performant, but at least data of base table is
not scattered around
61. Introduction to Enterprise JavaBeans 61
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
JOINED
CREATE TABLE GELDKARTE
(
NR INTEGER NOT NULL PRIMARY KEY,
GUTHABEN DECIMAL(7,2) NOT NULL
);
CREATE TABLE MIT_LIMIT
(
NR INTEGER NOT NULL PRIMARY KEY,
LIMIT DECIMAL(7,2) NOT NULL
);
CREATE TABLE AUSLANDSKARTE
(
NR INTEGER NOT NULL PRIMARY KEY,
LAND CHAR(30) NOT NULL
);
...
@Entity
@Table(name = "GELDKARTE")
@Inheritance(strategy = InheritanceType.JOINED)
public class GeldkarteTS {
private int nr;
private BigDecimal guthaben;
...
}
...
@Entity
@NamedQueries({@NamedQuery(name="MitLimitTCC.findAll",query=
"SELECT o FROM MitLimitTCC o") })
@Table(name = "MIT_LIMIT")
public class MitLimitTS extends GeldkarteTS {
private BigDecimal limit;
...
}
...
@Entity
@Table(name = "AUSLANDSKARTE")
public class AuslandskarteTCC extends MitLimitTCC {
private String land;
...
}
62. Introduction to Enterprise JavaBeans 62
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Which type is correct?
● ...it really depends on the structure of the
database
● What's nice:
● You do not rewrite the bean class, if you want to
change type: you adapt its annotation
● @MappedSuperclass
● The base class doesn't have to be an Entity Bean, it
can be also a usual class. Its subclasses are
mapped to tables (~ abstract class, there shall be
no instance of the base class in tables)
63. Introduction to Enterprise JavaBeans 63
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Timer Service
● Java EE comes with a service that offers timed
operation
● Shifts thread management from developer to
application server [making it safier ;)]
● A real life use case:
● Send GIS data via webservice
– Arrange data according to xsd and blocks of 200 units
each
– Send data block and obtain ticket (→ transmission)
– Query webservice for transmission outcome
64. Introduction to Enterprise JavaBeans 64
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Timer Service
● It's possible to use a Stateless Session Bean or
a Message-Driven Bean
● We can choose to implement
javax.ejb.TimedObject (and therefore
implement the method ejbTimeout(Timer
timer) or we choose to inject a reference by using
@Resource annotation
● Let's choose the latter :)
65. Introduction to Enterprise JavaBeans 65
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Timer Service...
@Stateless
public class GisTimeBean implements SomeRemoteableInterface {
@Resource TimeService timerService;
public void startGisTimerTS(){
GregorianCalendar cal = new GregorianCalenda();
cal.add(GregiorianCalendar.DATE,1);
Date tomorrow = calendar.getTime();
timerService.createTimer(tomorrow, „GIS“);
}
public void stopGisTimer(){
for (Object o : timerService.getTimers()){
Timer t = (Timer)o;
String info = t.getInfo().toString();
if(info.equalsIgnoreCase(„GIS“)){
t.cancel();
}
}
}
@Timeout
public void timeout(Timer timer){
String i = (String) timer.getInfo();
if (i.equalsIgnoreCase(„GIS“)){
//your logic here
}
}
}
66. Introduction to Enterprise JavaBeans 66
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Not covered
●
Annotations
● plenty much more of them and you can define your own
– e.g.: Life-Cycle-Annotations: @PostConstruct, @PostPersist, @PreRemove
● Transactions
● refers to the db content, not to the state of the entity beans!
– Container Managed Transaction vs Bean Managed Transaction
● CMT: by default, every method on a session bean called by a client requires a transaction
● If already in a transaction, a transactional method reuses it
● @TransactionAttribute allows fine tuning
– Transaction and Exceptions
● @ApplicationException and rollbacks
– Concurrent access
● Versioning
●
EJB QL
67. Introduction to Enterprise JavaBeans 67
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Not covered
● XML Mappings
● instead of annotations
● Interceptors and Entity Listener
● interceptors are put between caller and callee for administrative
tasks such as time measurement, protocol, etc.
● entity listener is a sentinel for entity beans, tied to its Life-Cycle-
Annotations
● Security
● role based method execution, functional rights management
– beans need to be part of a security domain, based on LDAP, relational
db, or simple textfiles, where users and roles are defined
● Web Services
68. Introduction to Enterprise JavaBeans 68
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
The tip of the iceberg
GPL
●JBoss Application Server
●Glassfish
●JonAS
●Apache Geronimo 2.0
●Apache OpenEJB
Proprietary
●SUN Java System
Application Server (JSAS)
●IBM WebSphere AS
Community Edition
●IBM Websphere Application
Server 7
●WebLogic Application Server
from Oracle
●Oracle Containers for Java
EE 11
●SAP Netweaver Application
Server
●JEUS 6
●NEC WebOTX
69. Introduction to Enterprise JavaBeans 69
AUTONOME PROVINZ BOZEN - SÜDTIROL PROVINCIA AUTONOMA DI BOLZANO - ALTO ADIGE
Bibliography
● Uwe Rozanski: Enterprise JavaBeans 3.0 mit Eclipse und
Jboss. Praxisbuch und Referenz. Mitp, Heidelberg, 2007.
ISBN: 978-3-8266-1699-0
● Bill Burke, Richard Monson-Faefel: Enterprise JavaBeans
3.0. O'Reilly, Sebastopol, 2006 ISBN-10: 0-596-00978-X
● Alberto Silitti: Internet Technologies 2. Free University Of
Bolzano/Bozen, 2006
● RedHat: JBoss Enterprise Application Platform Configuration
Guide.
http://www.redhat.com/docs/manuals/jboss/jboss-eap-4.2/doc/Se
● Sun Microsystems: The Java EE 5 Tutorial.
http://technology-related.com/javaee/5/docs/tutorial/doc/index.htm
Editor's Notes
Beispiel Person mit Adresse: In dieser Variante mappen wir 1:1, Person hat den FK und wir legen fest, daß eine Person 0/1 Adressen hat
Beispiel Person mit Adresse: In diesem Fall benutzen wir den PK aus Person in der Tabelle Adresse. Vorteil: Wenn wir morgen nicht mehr 0/1, sondern 0/n Beziehung zwischen Person und Adresse einrichten möchten, brauchen wir der Table Adresse nur eine weitere Spalte mit einer ID und einen composite Key zwischen PERID(PK von Person) und der neuen Spalte zu machen (Unique constraint)
Hier sollte ich die Zustandsänderung erwähnen: Objekt – Entity Bean – Objekt. Man muß dem EM quasi mitteilen, daß wir wieder eine Entity Bean haben möchten (merge())
Hier hingegen haben wir immer ein EntityBean, sofern der Einstiegspunkt immer derselbe ist (getItem und changeItem). Ansonsten wäre es ein NPE.
Sequence:
1) Client sends a message to a channel
2) MDBs are listening to the channel
3) MDB with the proper MessageSelector reacts
4) MDB does something using the message object
Example: geoLAFIS – Wechsel des Betriebsleiters
Nachricht: Betriebsleiter hat gewechselt
(Vater übergibt Betrieb an Sohn)
→ Tiere müssen übertragen werden (LafisVet)
→ Milchquoten umschreiben
→ Maschinen evtl. umschreiben
→ Willkommensschreiben für den neuen Betriebsleiter, vom LR unterschrieben
Sequence:
1) Client sends a message to a channel
2) MDBs are listening to the channel
3) MDB with the proper MessageSelector reacts
4) MDB does something using the message object
Example: geoLAFIS – Wechsel des Betriebsleiters
Nachricht: Betriebsleiter hat gewechselt
(Vater übergibt Betrieb an Sohn)
→ Tiere müssen übertragen werden (LafisVet)
→ Milchquoten umschreiben
→ Maschinen evtl. umschreiben
→ Willkommensschreiben für den neuen Betriebsleiter, vom LR unterschrieben
Zum Functional Rights Management:
Im Gegensatz zum RoleBased, daß den grundsätzlichen Zugriff regelt; wir müssen aber innerhalb der Methode die Rolle abfragen können:
Z.B. @RolesAllowed(„REGISTRIERTER_PARTNER“) zugriff auf eine Methode, in der man Bestellungen aufgibt. Ist der Warenwert der Bestellung jedoch &gt; 1000 muß der Kunde vom Typ „STAMMKUNDE“ sein, um die Bestellung voranzubringen.