16.13 JPA-Beispiel mit der NetBeans-IDE
JPA (Java Persistence API) ist ein Standard für objekt-relationales Mapping. Ohne zu detailliert in diesen Java EE-Standard einzusteigen, soll ein kleines Beispiel mit NetBeans zeigen, wie einfach es sein kann, Tabellenzeilen auf Objekte zu übertragen.
Der Ausgangspunkt für dieses Beispiel ist die Beispieldatenbank, die wir schon in Abschnitt 16.4.3, »Datenbankbrowser und eine Beispielabfrage unter NetBeans«, genutzt haben. Genau für diese Beispieldatenbank wollen wir Objekte generieren lassen, die die Dateninformationen repräsentieren. Die Objekte, die Tabellenzeilen repräsentieren, heißen Entity-Beans. Sie können von Hand aufgebaut, oder – diesen Weg gehen wir – automatisch aus der Datenbank generiert werden.
16.13.1 Entity-Beans generieren
Ein Projekt mit JDBC-Datenbankzugriff und dem JDBC-Treiber soll eingerichtet sein. Wähle dann File • New File... • Persistence und in der Box Entity Class from Database (siehe Abbildung 16.19).
Wähle Next, und im nächsten Dialog wähle bei der Database Connection die Beispieldatenbank aus (siehe dazu Abschnitt 16.4.3, »Datenbankbrowser und eine Beispielabfrage unter NetBeans«). In der linken Spalte erscheinen die Tabellen. Wählen wir Add All >>, um für alle Tabellen Entity-Beans zu generieren (siehe Abbildung 16.20).
Abbildung 16.19: NetBeans-Dialog zum Anlegen neuer Entity-Klassen
Abbildung 16.20: Tabellen für den Quellcode-Generator hinzufügen
Nach Next erscheint ein neuer Dialog. Einstellungen sind nur beim Paket nötig. Ich wähle com.tutego.insel.jpa:
Abbildung 16.21: Wählen des Paketnamens und Abschluss des Dialogs
Danach ist ein Finish fällig.
16.13.2 Die Quellen im Überblick
Der Generator hat eine ganze Reihe von Dateien generiert und Eintragungen gemacht:
- Neue Java-Archive stehen im Klassenpfad. Sie enthalten die JPA-Annotationen und den JPA-Provider EclipseLink (die Referenzimplementierung für JPA).
- Die Entity-Bean-Klassen wurden generiert – ihr Name stammt vom Tabellennamen.
- Ein META-INF-Verzeichnis führt die Datei persistence.xml auf.
Abbildung 16.22: Generierte Dateien
Die Customer-Klasse repräsentiert die CUSTOMER-Tabelle. Ein Ausschnitt aus der Datei sieht so aus:
@Entity
@Table(name = "CUSTOMER")
@NamedQueries({
@NamedQuery(name = "Customer.findAll", query = "SELECT c FROM Customer c"),
@NamedQuery(name = "Customer.findByCustomerId", query = "SELECT c FROM Customer c
WHERE c.customerId = :customerId"),
...
@NamedQuery(name = "Customer.findByCreditLimit", query = "SELECT c FROM Customer c
WHERE c.creditLimit = :creditLimit")})
public class Customer implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "CUSTOMER_ID")
private Integer customerId;
@Basic(optional = false)
@Column(name = "ZIP")
private String zip;
...
public Customer() {
}
...
public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
...
}
Es lässt sich festhalten, dass es für jede Spalte in der Tabelle ein Attribut und Setter/Getter gibt. Die anderen Beans sehen im Prinzip genauso aus.
16.13.3 Persistence Unit
Die Datei im META-INF-Vezeichnis ist eine sogenannte PU-Datei (für Persistence Unit). Sie zählt alle Klassen auf und enthält die Zugangsdaten zur Datenbank.
Abbildung 16.23: Editor mit persistence.xml
Der Persistence-Unit-Name ist InselPU, und diesen Namen brauchen wir später noch.
16.13.4 Ein JPA-Beispielprogramm
Der NetBeans-Editor hat extra einen eigenen Menüpunkt für JPA, sodass es einfach ist, ein kleines Beispiel aufzubauen. Beginnen wir mit einer Standard-Klasse. (Das geht in NetBeans über File • New File... • Java • Java Class.) Nennen wir die Klasse JpaDemo.
Daraufhin öffnet sich der Editor mit der neuen Klasse.
import com.tutego.insel.jpa.Customer;
import com.tutego.insel.jpa.DiscountCode;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class JpaDemo
{
public static void main( String[] args )
{
EntityManagerFactory emf = Persistence.createEntityManagerFactory( "InselPU" );
EntityManager em = emf.createEntityManager();
try
{
DiscountCode discountCode = em.find( DiscountCode.class, 'H' );
Customer customer1 = new Customer( 888 );
customer1.setName( "Chris" );
customer1.setZip( "999" );
customer1.setDiscountCode( discountCode );
em.getTransaction().begin();
em.persist( customer1 );
em.getTransaction().commit();
String query = "SELECT c FROM Customer c";
for ( Customer c : em.createQuery( query, Customer.class ).getResultList() )
System.out.println( c.getName() );
}
catch ( Exception e )
{
e.printStackTrace();
em.getTransaction().rollback();
}
finally
{
em.close();
}
}
}
Das Programm besorgt sich Zugang zum OR-Mapper – vereinfacht gesagt repräsentiert als EntityManager-Objekt. Der EntityManager bietet Methoden wie persist() zum Speichern oder find() zum Suchen. Der erste JPA-Code erfragt ein DiscountCode-Objekt, was mit der ID 'H' in der Datenbank steckt. Mit diesem Discount-Code legen wir einen neuen Kunden an. Anschließend geben wir alle Kunden aus, und der neue Kunde ist natürlich dabei:
JumboCom
Livermore Enterprises
Oak Computers
Nano Apple
HostProCom
CentralComp
Golden Valley Computers
Top Network Systems
West Valley Inc.
Ford Motor Co
Big Car Parts
New Media Productions
Yankee Computer Repair
Chris
Wenn es einen Fehler der Art »Exception in thread "main" javax.persistence.PersistenceException: Exception [EclipseLink-4003] (Eclipse Persistence Services – 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException« gibt, dann fehlt der JDBC-Treiber für die Derby-Datenbank; Abschnitt 16.4.3 erklärt, wie er einzubinden ist.
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.