EJB 3.0 EINFÜHRUNG UND STATUS

Werbung
EJB 3.0
EINFÜHRUNG UND STATUS
Peter Doschkinow
Software Architekt
Sun Microsystems
1
Agenda
• Motivation
• EJB 3.0 Programmier-Modell
• Java Persistence API (JPA)
• Aktueller Status und Zusammenfassung
2
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
3
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
4
Beispiel: EJB 2.x Interfaces
// EJB 2.x Stateless Session Bean: Remote Interface
public 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 Interface
public interface CalculatorHome extends EJBHome {
}
5
Calculator create() throws CreateException,
RemoteException;
Beispiel: EJB 2.x Implementation
// EJB 2.x Stateless Session Bean Implementation
public 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; }
}
6
Beispiel: EJB 2.x Descriptor
<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>
...
7
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
8
Agenda
• Motivation
• EJB 3.0 Programmier-Modell
• Java Persistence API (JPA)
• Aktueller Status und Zusammenfassung
9
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
10
Beispiel
// EJB 3.0 business interface (POJI)
@Remote
public interface Calculator {
int add (int a, int b);
int subtract (int a, int b);
}
// EJB 3.0 stateless session bean (POJO)
@Stateless
public class CalculatorBean implements Calculator {
public int add (int a, int b) { return a + b;}
public int subtract (int a, int b) { return a – b;}
}
11
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
12
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
13
Beispiel
// EJB 3.0 Stateless Session Bean: Bean Class
// Data access using injection and Java Persistence
API
@Stateless
public class PayrollBean implements Payroll {
@PersistenceContext EntityManager em;
public void setSalary(int empId,int salary) {
em.find(Employee.class,empId).setSalary(salary);
}
...
}
14
Beispiel
// EJB 3.0 Stateless Session Bean: Bean Class
// Data access using dynamic lookup and JPA
@PersistenceContext(name=“PayrollPC“)
@Stateless
public 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);
}
...
15
}
Vereinfachung der Client-Ansicht
• durch Verwendung von Dependency Injection
• einfache Business Interface Ansicht
• kein Home interface
• keine RemoteExceptions
• keine Notwendigkeit andere checked Exceptions
abzufangen
16
Beispiel
// EJB 3.0: Client View
@EJB Payroll payroll;
// Use the bean
payroll.setSalary(1234, 4000);
17
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
18
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)
{
...
}
}
19
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();
}
...
20
}
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 MethodenEbene definiert werden
21
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
22
Agenda
• Motivation
• EJB 3.0 Programmier-Modell
• Java Persistence API (JPA)
• Aktueller Status und Zusammenfassung
23
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
24
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
25
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)
26
Beispiel
@Entity
public 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;}
27
}
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
28
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
29
> Zustand einer Detached-Entity zurück auf Managed-Entity kopieren
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;
}
}
30
Java Persistence Query Language
• eine Erweiterung von EJB QL
> wie EJB QL, SQL-ähnlich
• hinzugefügte Funktionalität
>
>
>
>
>
>
>
31
Projektions-Liste (SELECT Klausel)
explizite JOINS
Sub-Queries
GROUP BY, HAVING
EXISTS, ALL, SOME/ANY
UPDATE, DELETE Operationen
...
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
32
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();
}
33
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
34
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
35
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ümerund eine Umkehrseite
> sie werden von der Anwendung, nicht vom Container verwaltet
• Eigentümer-Seite bestimmt das physische Mapping
> legt den Fremdschlüssel fest
36
Beispiel
@Entity public class Customer {
@Id protected Long id;
@OneToMany(mappedBy=“cust”)
// reverse side
protected Set<Order> orders = new HashSet();
public Set<Order> getOrders() {return orders;}
public void addOrder(Order order) {
getOrders().add(order);
order.setCustomer(this);}
...
}
37
@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;}
...
}
OneToMany/ManyToOne Mapping
@Entity
public class Customer {
@Id
int id;
...
CUSTOMER
ID
...
@OneToMany(mappedBy=“cust”)
Set<Order> orders;
}
ORDER
@Entity
public class Order{
@Id
int id;
...
@ManyToOne
Customer cust;
38
}
ID
...
CUST_ID
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
39
Objektmodell
Animal
id: int
name: String
LandAnimal
legCount: int
40
AirAnimal
wingSpan: int
Zugehöriges Datenmodell
• Single table:
ANIMAL
ID
DISC
NAME
LEG_COUNT
WING_SPAN
ANIMAL
ID
LAND_ANIMAL
• Joined:
ID
• Table per Class:
41
NAME
LEG_COUNT
AIR_ANIMAL
ID
LAND_ANIMAL
ID
NAME
LEG_COUNT
WING_SPAN
AIR_ANIMAL
ID
NAME
WING_SPAN
Agenda
• Motivation
• EJB 3.0 Programmier-Modell
• Java Persistence API (JPA)
• Aktueller Status und Zusammenfassung
42
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
43
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
44
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
45
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
46
EJB 3.0
EINFÜHRUNG UND STATUS
Peter Doschkinow
[email protected]
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!
48
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
49
Annotations für EnvironmentZugriff
• @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
50
Transaktionsattribute
container managed transactions
• 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
51
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
52
Beispiel
// EJB 3.0: Event Notification
@Stateful public class TravelBookingBean
implements TravelBooking {
@PostConstruct
@PostActivate
private void connectToBookingSystem() {...}
@PreDestroy
@PrePassivate
private void disconnectFromBookingSystem() {...}
...
}
53
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
54
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
55
Entity Lifecycle
New
per
sis
t()
update
Managed
remove()
Removed
56
nd
e
PC
Detached
()
rge
e
m
Relationen zwischen Entitäten
• One-to-one, one-to-many, many-to-many, many-toone 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
57
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
58
Simple Mappings
@Entit
public class Customer {
y
@Id
int id;
String name;
@Column(name=“CRED
IT”)
int c_rating;
@Lo
b
Image photo;
}
59
CUSTOMER
ID
NAME
CREDIT
PHOTO
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>
60
Many-to-Many Mapping
@Entity
public class Customer {
...
@ManyToMany
@JoinTable(table=“CUST_PHONE”),
joinColumns=@JoinColumn(name=“CUST_ID”),
inverseJoinColumns=@JoinColumn(name=“PHON_ID”))
Collection<Phone> phones;
}
PHONE
CUSTOMER
ID
...
CUST_PHONE
CUST_ID
61
PHON_ID
ID
...
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>
62
Vererbung
von
@MappedSuperclass public class Person {
MappedSuperclass
@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;
}
63
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)
64
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();
}
}
65
Herunterladen