Post on 12-Aug-2019
transcript
1
EJB 3.0EINFÜHRUNG UND STATUSPeter DoschkinowSoftware ArchitektSun Microsystems
2
Agenda
• Motivation• EJB 3.0 Programmier-Modell• Java Persistence API (JPA)• Aktueller Status und Zusammenfassung
3
EJB Status vor EJB 3.0
• EJB 2.1 ist sehr mächtig, aber zu komplex• Ursprungsziel der EJB Technologie> Bereitstellung einer kontrollierten Umgebung zur Unterstützung
und Ablauf von Enterprise-Anwendungen• Container-Aufgaben> bietet eine Ablaufumgebung und Dienste für die Komponenten an,
indem er die Aufrufe ihrer Clients abfängt> bereitgestellte Dienste>Nebenläufigkeit, Remoting, Transaktionen, EIS-Integration> Environment-Zugriff, Ressource-Pooling, Sicherheit, Persistence
4
Das Problem
• um Dienste vom Container zu benutzen, mußte man umfangreiche Container-API implementieren statt sich auf die Anwendung zu konzentrieren> EJBHome interface> EJBObject interface> EnterpriseBean interfaces> JNDI interfaces> Deployment descriptor> …
• die Vorteile der Verwendung von EJB mußten durch ein komplexes Programmiermodell erkauft werden
5
// EJB 2.x Stateless Session Bean: Remote Interfacepublic interface Calculator extends EJBObject {int add (int a, int b) throws RemoteException;int subtract (int a, int b)throws RemoteException;}
// EJB 2.x Stateless Session Bean: Home Interfacepublic interface CalculatorHome extends EJBHome {Calculator create() throws CreateException, RemoteException;}
Beispiel: EJB 2.x Interfaces
6
// EJB 2.x Stateless Session Bean Implementationpublic class CalculatorBean implements SessionBean { private SessionContext ctx; public void setSessionContext(SessionContext s) {
ctx = s; } public void ejbCreate() { } public void ejbActivate () { } public void ejbPassivate () { } public void ejbRemove () { }
public int add (int a, int b) { return a + b; } public int subtract (int a, int b) { return a – b; }
}
Beispiel: EJB 2.x Implementation
7
<session> <ejb-name>CalculatorEJB</ejb-name> <home>com.example.CalculatorHome</home> <remote>com.example.Calculator</remote> <ejb-class>com.example.CalculatorBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session>
...
Beispiel: EJB 2.x Descriptor
8
Der Ansatz von EJB 3.0
• mehr Arbeit wird vom Container getan, weniger vom Entwickler• die Schnittstelle zwischen Container und Entwickler
begünstigt den Entwickler, nicht den Container> Bean bestimmt ihre Bedürfnisse durch Metadaten> Implementierung von Container Interfaces entfällt> Deployment Descriptor nicht mehr notwendig> vernünftige Defaults, Konfiguration nur der Ausnahmen
• der Container stellt nur die von der Bean angeforderten Dienste zur Verfügung
9
Agenda
• Motivation• EJB 3.0 Programmier-Modell• Java Persistence API (JPA)• Aktueller Status und Zusammenfassung
10
Bean Klassen• Session Beans und Message-Driven Beans sind
einfache Java Klassen – Rückkehr der POJOs!> sie müssen nicht Container-Interfaces implementieren > der Bean Typ wird durch Annotations oder XML bestimmt
• Annotations der Bean Klasse> @Stateless, @Stateful, @MessageDriven
• EJB 2.x Entity Beans unverändert> nicht zu empfehlen, vermutlich künftig 'deprecated'> JPA-Entitäten liefern neue Funktionalität> @Entity ist nur auf JPA-Entitäten anwendbar
• Business Interfaces sind POJI
11
Beispiel// EJB 3.0 business interface (POJI)@Remotepublic interface Calculator { int add (int a, int b); int subtract (int a, int b);}
// EJB 3.0 stateless session bean (POJO)@Statelesspublic class CalculatorBean implements Calculator { public int add (int a, int b) { return a + b;}
public int subtract (int a, int b) { return a – b;}}
12
Zugriff auf die Environment
• Über Dependency Injection oder einfaches Look-Up> die Benutzung der JNDI Interfaces nicht mehr nötig
• die Abhängigkeiten der Komponente werden über Annotations oder XML ausgedrückt• bei Anwendung der Annotations auf:> Instanz Variable oder Property-Setter => Injection> Bean Klasse => dynamisches Look-Up
13
Dependency Injection
• die Bean Instanz wird zum Zeitpunkt ihrer Erstellung mit Referenzen auf Environment-Ressourcen versorgt • die Reihenfolge der Injections ist nicht definiert• optional wird die @PostConstruct-Methode
aufgerufen, nachdem die Injection abgeschlossen ist
14
Beispiel// EJB 3.0 Stateless Session Bean: Bean Class// Data access using injection and Java Persistence API
@Statelesspublic class PayrollBean implements Payroll {
@PersistenceContext EntityManager em;
public void setSalary(int empId,int salary) { em.find(Employee.class,empId).setSalary(salary);}...
}
15
Beispiel// EJB 3.0 Stateless Session Bean: Bean Class// Data access using dynamic lookup and JPA
@PersistenceContext(name=“PayrollPC“)@Statelesspublic class PayrollBean implements Payroll {
@Resource SessionContext ctx;
public void setSalary(int empId,int salary) { EntityManager em = ctx.lookup(“PayrollPC“); em.find(Employee.class,empId).setSalary(salary);}...
}
16
Vereinfachung der Client-Ansicht
• durch Verwendung von Dependency Injection• einfache Business Interface Ansicht• kein Home interface• keine RemoteExceptions • keine Notwendigkeit andere checked Exceptions
abzufangen
17
Beispiel
// EJB 3.0: Client View@EJB Payroll payroll;
// Use the beanpayroll.setSalary(1234, 4000);
18
Transaktionen
• Container-managed transactions> sind default
• Bean-managed transactions> die Komponente verwendet UserTransaction API
• Annotation: @TransactionManagement> mit Werten CONTAINER (default) oder BEAN> die Annotation wird auf die Bean Klasse angewendet
• Annotation: @TransactionAttribute> Werte: REQUIRED (default), REQUIRES_NEW, MANDATORY,
NEVER, NOT_SUPPORTED, SUPPORTS
19
Beispiel// EJB 3.0: Container-managed transactions@Stateless public class PayrollBean implements Payroll {
@TransactionAttribute(MANDATORY)public void setSalary(int empId,int salary) {
...}
public int getSalary(int empId){
...}
}
20
Beispiel// EJB 3.0: Bean-managed transactions@TransactionManagement(BEAN)@Stateless public class PayrollBean implements Payroll {
@Resource UserTransaction utx;@PersistenceContext em;
public void setSalary(int empId,int salary) { utx.begin(); em.find(Employee.class,empId).setSalary(salary); utx.commit();}...
}
21
Interceptors
• ermöglichen AOP in EJB-Anwendungen• können für Session und Message-Driven Beans
definiert werden• das Aufruf-Modell: “around” methods> umschliesst den Aufruf von Business-Methoden> kann Aufruf-Parameter und Ergebnisse manipulieren
• können auf EJB-Modul-, Bean-, oder Methoden-Ebene definiert werden
22
Deployment Descriptors
• verfügbar als Alternative zu Annotations• benötigt für Metadaten auf Anwendungs-Ebene> z.B. default Interceptoren
• können benutzt werden um manche Annotations zu überschreiben• nützlich für hinausgeschobene Konfigurationen> z.B. für die Festlegung der Security-Attribute
• nützlich für diverse Konfigurationen> Java Persistence API O/R mapping
• können 'sparse', vollständig und/oder durch Annotations ergänzt werden
23
Agenda
• Motivation• EJB 3.0 Programmier-Modell• Java Persistence API (JPA)• Aktueller Status und Zusammenfassung
24
Hintergrund
• JPA ist Teil von JSR-220 (EJB 3.0)• angefangen als Vereinfachung für Entity Beans> ausgeweitet als Persistenz-Technologie für POJOs
• erweitert um Java EE und Java SE Umgebungen zu unterstützen• Referenz-Implementierung ist Bestandteil vom
Projekt GlassFish> Oracle TopLink Essentials> Oracle hat sich Sun bei der Leitung der Spezifikation in Juni
2005 angeschlossen
25
Hauptmerkmale
• POJO-basiertes Persistenz-Modell> einfache Java Klassen, keine Komponenten
• Unterstützung für umfangreiche Domain-Modellierung> Vererbung, Polymorphismus, etc.
• erweiterte Abfragesprache• standardisiertes O/R Mapping > unter Verwendung von Annotations und/oder XML
• verwendbar in Java EE und Java SE Umgebungen• Unterstützung für pluggable Persistenz-Provider
26
Entitäten
• Plain old Java objects> erstellt mit new> keine Anforderungen für Interfaces> besitzen persistente Identität> können persistenten und nicht-persistenten Zustand haben> einfache Typen (primitive, Wrappers, enums, serializables)> zusammengesetzte abhängige Typen (z.B. Addresse)> nicht-persistenter Zustand(transient oder @Transient)
> serializable – verwendbar als Detached Objects> eliminieren den Bedarf an Data Transfer Objects(DTOs)
27
@Entitypublic class Customer implements Serializable {
@Id protected Long id;protected String name;@Embedded protected Address address;protected PreferredStatus status;@Transient protected int orderCount;
public Customer() {}
public Long getId() {return id;}protected void setId(Long id) {this.id = id;}
public String getName() {return name;}public void setName(String name) {this.name = name;}
}
Beispiel
28
Persistence Context
• eine Menge von Entitäten, die von einem EntityManager verwaltet werden• eindeutige Entity-Instanz für jede persistente Identität• alle Entity-Instanzen gehören zur selben Persistence
Unit(PU), abgebildet auf dieselbe DB> die PU ist eine Einheit für Packaging und Deployment
• EntityManager API ist die Schittstelle zum Persistence Context und Persisitence Provider> Lebenszyklus-Verwaltung von Entitäten, Suche von Entitäten nach
Id, Factory für Queries
29
Entity Lifecycle
• new> Erstellung einer neuen Entity-Instanz> die Entität ist noch nicht managed oder persistent
• persist> die Entität wird gemanaged> wird in der DB persistiert, wenn die Transaktion committed wird
• remove> die Entität wird glöscht> wird von der DB gelöscht, wenn die Transaktion committed wird
• refresh> der Zustand der Entität wird von der DB geladen
• merge> Zustand einer Detached-Entity zurück auf Managed-Entity kopieren
30
Beispiel@Stateless public class OrderManagementBean
implements OrderManagement {…@PersistenceContext EntityManager em;…public Order addNewOrder(Customer customer,
Product product){
Order order = new Order(product);customer.addOrder(order);em.persist(order);return order;
}}
31
Java Persistence Query Language
• eine Erweiterung von EJB QL > wie EJB QL, SQL-ähnlich
• hinzugefügte Funktionalität> Projektions-Liste (SELECT Klausel)> explizite JOINS> Sub-Queries> GROUP BY, HAVING> EXISTS, ALL, SOME/ANY> UPDATE, DELETE Operationen> ...
32
Queries
• statische Queries> definiert mit Annotaions oder XML> Annotations: @NamedQuery, @NamedNativeQuery
• dynamische Queries> der Query-String wird zur Laufzeit festgelegt
• man kann JPA-Queries oder SQL verwenden• es gibt Benannte- oder Positions-Parameter• EntityManager ist Factory für Query Objekte> createNamedQuery, createQuery, createNativeQuery
• Query-Methoden zur Kontrolle von Ergebnissen, Seitenumbruch, Flush-Mode
33
Dynamische Abfrage
@PersistenceContext EntityManager em;
…public List findByZipcode(String personType, int zip) {
return em.createQuery ( “SELECT p FROM ” + personType
+ “ p WHERE p.address.zip = :zipcode”)
.setParameter(“zipcode”, zip)
.setMaxResults(20)
.getResultList();}
34
Object/Relational Mapping
• bildet den persistenten Objektzustand in relationale DB ab• Abbildung von Relationen zu anderen Entitäten• Mapping-Metadaten können Annotations und/oder XML sein• Annotations> logisch—Object Modell (@OneToMany, @Id, @Transient)> physisch—DB Tabellen und Spalten (@Table, @Column)
• XML> Elemente für das Mapping von Entitäten und ihre Felder/Properties
• Regel für Default-Werte von DB Tabellen- und Spalten-Namen
35
Object/Relational Mapping
• Zustand oder Relationen können EAGER oder LAZY geladen werden> LAZY ist ein Hinweis, dass der Container das Laden bis zum
Zugriff auf die Felder/Relationen zurückstellt> EAGER verursacht, dass die Felder/Relationen geladen werden
sobald die referenzierende Entität geladen wird• Kaskadierung von Operationen auf referenzierte
Entitäten> kann pro Relation über @Cascade festgelegt werden> kann auch global im Mapping File definiert werden
36
Abbildung von Entity-Relationen
• Unterstützung aller gängiger Beziehungen> @ManyToOne, @OneToOne — zu einzelnen Entitäten> @OneToMany, @ManyToMany — Sammlung von Entitäten
• bidirektionale Beziehungen haben eine Eigentümer- und eine Umkehrseite> sie werden von der Anwendung, nicht vom Container verwaltet
• Eigentümer-Seite bestimmt das physische Mapping> legt den Fremdschlüssel fest
37
@Entity public class Customer {@Id protected Long id;@OneToMany(mappedBy=“cust”) // reverse sideprotected Set<Order> orders = new HashSet();public Set<Order> getOrders() {return orders;}public void addOrder(Order order) {
getOrders().add(order);order.setCustomer(this);}
...}
@Entity public class Order {@Id protected Long id;@ManyToOne protected Customer cust; // owning side
public Customer getCustomer() {return cust;}public void setCustomer(Customer cust) {this.cust = cust;}
...}
Beispiel
38
public class Order{
int id; ... Customer cust;}
public class Customer { int id; ... Set<Order> orders;}
OneToMany/ManyToOne Mapping
CUSTOMERID . . .
ORDERCUST_IDID . . .@Entity
@ManyToOne
@Id
@Entity@Id
@OneToMany(mappedBy=“cust”)
39
Vererbung
• Entittäten können vererben von> anderen Entitäten — konkret oder abstrakt> Mapped Superklassen> für gemeinsamen Zustand und Annotations
> Klassen, die keine Entitäten sind — konkret oder abstrakt• Abbildung der Vererbungs-Hierarchie> SINGLE_TABLE> JOINED> TABLE_PER_CLASS
40
Objektmodell
AirAnimal
wingSpan: int
LandAnimal
legCount: int
Animal
id: intname: String
41
Zugehöriges Datenmodell
• Single table: ANIMALLEG_COUNTID DISC NAME WING_SPAN
ANIMALID NAME
LAND_ANIMALID LEG_COUNT
AIR_ANIMALID WING_SPAN
LAND_ANIMALID LEG_COUNT
AIR_ANIMALID WING_SPANNAMENAME
• Joined:
• Table per Class:
42
Agenda
• Motivation• EJB 3.0 Programmier-Modell• Java Persistence API (JPA)• Aktueller Status und Zusammenfassung
43
Aktueller Status
• Final Release von EJB 3.0 in Mai 2006• Java EE 5 Referenz-Implementierung in Mai 2006> Teil vom Open-Source Projekt GlassFish
• EJB 3.0 Preview-Container von Oracle, JBoss, BEA, SAP• wachsende Unterstützung von Tools> NetBeans 5.5, Eclipse, IntelliJ, JBuilder, ...
• Hauptprobleme beseitigt, Bedarf an Frameworks, die Java EE unterstützen, nimmt ab
44
Zusammenfassung EJB 3.0
• deutliche Vereinfachung der EJB-Technologie für Entwickler> Beans sind POJOs mit POJIs> APIs neu konzipiert um benutzerfreundlich zu sein> leichter Zugang zu Container-Diensten und Umgebung> Deployment Descriptors sind verfügbar aber nicht zwingend notwendig
• EJB 3.0 Komponenten sind kompatibel mit bestehenden J2EE-Komponenten• mächtige und leicht verwendbare Funktionalität
45
Zusammenfassung JPA
• Entitäten sind einfache Java Klassen> leicht zu erstellen und intuitiv zu benutzen> können zu anderen Tiers und Servern übertragen werden
• EntityManager> einfaches API zur Verwaltung von Entitäten> verwendbar in Java EE und Java SE Umgebungen
• Standardisierung> O/R Mapping kann Annotations oder XML bentutzen> benannte, statische und dynamische Query-Definitionen> SPI für pluggable Persistence Provider
46
Links
• Spezifikationen> http://jcp.org/en/jsr/detail?id=220
• JavaOne 2006 Sessions> alle PDFs zum Thema Java EE gepackt in
http://java.sun.com/javaone/sf/2006/sessions/java_ee.zip> TS-3396, TS-3395, TS-9056, TS-1365, TS-1887
• Glassfish: Java EE 5 Referenz-Implementierung> http://glassfish.dev.java.net
• Java Application Platform SDK> http://java.sun.com/javaee/downloads/index.jsp
Peter Doschkinowpeter.doschkinow@sun.com
EJB 3.0EINFÜHRUNG UND STATUS
48
Was fällt auf?
• eine Reihe von Schwachstellen> 3 Klassen und ein Deployment Descriptor> die Interfaces sind störend> create-Methode kreiert nicht> remove-Methode löscht nicht> alle javax.ejb.SessionBean Methoden sind unnötig> der Anwendungs-Code wird unübersichtlich
> der Deployment Descriptor enthält redundante Informationen• das Ziel von EJB 3.0 ist diese Probleme zu
beseitigen!
49
Business Interfaces• einfache Java Interfaces (POJI)
● keine Abhängigkeit mehr von EJBObject, EJBHome
• entweder für Local- oder Remote-Zugriff> Local-Zugriff ist default> Remote-Zugriff durch Annotation oder Deployment Descriptor> Remote-Methoden müssen nicht RemoteException aufwerfen
• Annotations: @Remote, @Local, @WebService> kann für die Bean-Klasse oder Interface spezifiziert werden
• eine Bean Klasse kann mehrere Business Interfaces haben> sie müssen dann explizit als solche durch Local/Remote-Annotations oder
Deployment Descriptor ausgewiesen sein
50
Annotations für Environment-Zugriff
• @Resource● für Connection Factories, Environment-Variablen, Topics/Queues,
EJBContext, UserTransaction, etc.
• @EJB> für EJB Business Interfaces oder EJB Home Interfaces
• @PersistenceContext> für Container-managed EntityManager
• @PersistenceUnit> für EntityManagerFactory
51
Transaktionsattribute
• die Annotations werden auf die Bean Klasse und/oder ihre Methoden angewandt● Anwendung auf die Bean Klasse gilt für alle Methoden, falls nicht auf
Methoden-Ebene überschrieben● Anwendung auf eine Methode gilt nur für die Methode
• Annotation: @TransactionAttribute> Werte: REQUIRED (default), REQUIRES_NEW, MANDATORY,
NEVER, NOT_SUPPORTED, SUPPORTS
container managed transactions
52
Lifecycle Callbacks • EJB 2.1 postuliert EnterpriseBean Interfaces• EJB 3.0 ermöglicht die Angabe nur von Events, die man benötigt• Annotations:
> @PostConstruct> @PreDestroy> @PostActivate> @PrePassivate
• Annotations können auf Methoden einer Bean- oder Interceptor Klasse angewandt werden
• dieselbe Methode kann für verschiedene Lifecycle Events dienen
53
Beispiel// EJB 3.0: Event Notification
@Stateful public class TravelBookingBean implements TravelBooking {
@PostConstruct@PostActivateprivate void connectToBookingSystem() {...}
@PreDestroy@PrePassivateprivate void disconnectFromBookingSystem() {...}
...}
54
Interceptoren• Default Interceptoren> angewendet auf alle Business-Methoden von EJBs im EJB-Modul> festgelegt im Deployment Descriptor
• Interceptoren auf Bean-Ebene> greifen auf alle Business-Methoden der Bean Klasse
• Interceptoren auf Methoden-Ebene> angewendet nur auf eine spezifische Business-Methode
• flexible Anpassungen in Bezug auf die Reihenfolge und Anwendung der Interceptoren möglich
55
Identität einer Entity• jede Entität hat eine persistente Identität> abgebildet auf den Primary Key in der DB
• kann einfachen Typ haben> Annotations>@Id — für einzelne Felder/Properties in der Entity Klasse>@GeneratedValue — der Wert wird automatisch erzeugt
• kann Benutzer-definierten Typ haben> Annotations>@EmbeddedId — für ein Feld/Property>@IdClass — entspricht mehreren Id Felder/Properties
• definiert an der Wurzel einer Entity-Hierarchie
56
Entity Lifecycle
New
Removed
Managed
Detached persist() PC end
merge()
remove()
update
57
Relationen zwischen Entitäten
• One-to-one, one-to-many, many-to-many, many-to-one Relationen zwischen Entitäten> Unterstützung für Collection, Set, List, Map Typen
• können unidirektional oder bidirektional sein> bidirektionale Relationen werden von der Anwendung, nicht vom
Container verwaltet> bidirektionale Relationen haben eine Eigentümer- und eine
Umkehr-Seite
58
Einfache Mappings
• direkte Abbildung von Felder/Properties auf Spalten• anwendbar für alle einfache Java Typen> primitive Typen, Wrapper-Typen, Date, Serializable, byte[ ], ...
• benutzt in Verbindung mit @Column • können Default-Werte überschreiben
59
Simple Mappings
public class Customer {
int id;
String name;
int c_rating;
Image photo;}
CUSTOMERID NAME CREDIT PHOTO
@Entity @Id
@Lob
@Column(name=“CREDIT”)
60
Simple Mappings
<entity class=“com.acme.Customer”> <attributes> <id name=“id”/> <basic name=“c_rating”> <column name=“CREDIT”/> </basic> <basic name=“photo”><lob/></basic> </attributes></entity>
61
Many-to-Many Mapping
PHON_IDCUST_ID
CUSTOMERID . . .
PHONEID . . .
CUST_PHONE
@Entitypublic class Customer { ... @ManyToMany @JoinTable(table=“CUST_PHONE”), joinColumns=@JoinColumn(name=“CUST_ID”), inverseJoinColumns=@JoinColumn(name=“PHON_ID”)) Collection<Phone> phones;}
62
Many-to-Many Mapping<entity class=“com.acme.Customer”> <attributes> ... <many-to-many name=“phones” <join-table name=“CUST_PHONE”> <join-column name=“CUST_ID”/> <inverse-join-column name=“PHON_ID”/> </join-table> </many-to-many> </attributes></entity>
63
@MappedSuperclass public class Person {@Id protected Long id;protected String name;@Embedded protected Address address;
}
@Entity public class Customer extends Person { @Transient protected int orderCount;
@OneToMany protected Set<Order> orders = new HashSet();
}
@Entity public class Employee extends Person {@ManyToOne protected Department dept;
}
Vererbung von MappedSuperclass
64
Persistenz in Java SE • keine Deployment-Phase> die Anwendung muß über ein “Bootstrap API” eine
EntityManagerFactory bekommen• verwendet Ressource-Local EntityManagers> die Anwendung benutzt lokale Transaktionen, die vom
EntityManager bereitgestellt werden• neuer Persistence Context für jeden neuen
EntityManager> keine Weiterleitung vom Persistence Context(wie im EJB-
Container)
65
Beispiel public class SalaryChanger { public static void main(String[] args) { EntityManagerFactory emf = Persistence .createEntityManagerFactory(“HRSystem”); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); Employee emp = em.find( Employee.class, new Integer(args[0])); emp.setSalary(new Integer(args[1])); em.getTransaction().commit(); em.close(); emf.close(); }}