Komponenten-basierte Entwicklung Teil 14: Persistenz mit

Werbung
Komponenten-basierte Entwicklung
Teil 14: Persistenz mit Hibernate-JPA
Teil 1
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
13.01.15 1
Literatur
[14-1]
Müller, Bernd; Wehr, Harald: Java Persistence API 2. Hanser, 2012.
[14-2]
http://www.jpainfo.de/projekte/download.html
[14-3] Beeger, Robert et al.: Hibernate. Persistenz in Java-Systemen mit
Hibernate 3. dpunkt, 2006
[14-4] http://sourceforge.net/projects/hibernatesample/
[14-5] http://hibernate.org/
[14-6] http://mvnrepository.com/artifact/org.hibernate
[14-8] http://upload.wikimedia.org/wikipedia/commons/8/81/Java_Persistence.p
df
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
2
Was macht Hibernate?
• Hibernate realisiert die JPA-Schnittstelle in der Version 2.0.
Siehe: http://de.wikipedia.org/wiki/Hibernate_(Framework)
• JPA = Java Persistence API
Siehe: http://de.wikipedia.org/wiki/Java_Persistence_API
Die Fehlermeldungen sind meist besser als beim nativen Hibernate,
trotzdem noch grausig.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
3
Maven und Hibernate
<hibernate.version>4.3.7.Final</hibernate.version>
… … …
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
Es soll nur die Java-API
</dependency>
benutzt werden.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
<exclusions>
<exclusion>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
</exclusion>
</exclusions>
</dependency>
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
4
Klasse Person I
@Entity
public class Person implements Serializable {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
public Person() {}
public Person(String firstName, String lastName) {
this.firstName= firstName;
this.lastName= lastName;
}
… … Getter und Setter … …
@Override public String toString() {
return String.format("####---Id=%d: %s %s",id,firstName,
lastName);
}
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
5
Klasse Person II - Bemerkungen
• Alle Beans oder POJOs heißen nun einfach Entities.
• Diese müssen mit @Entity eingeleitet werden.
• Es muss ein ID-Attribut vorhanden sein, meistens id genannt.
Dieses sollte ein Long oder ein String sein.
• Bei der Verwaltung bzw. Erzeugung der IDs gibt es
unterschiedliche Strategien, hier die „automatische":
@Id @GeneratedValue(strategy= GenerationType.AUTO)
• Alle Attribute müssen mit Getter/Setter-Funktionen versehen
werden.
• Attribute mit Getter/Setter-Funktionen werden Properties
genannt (Mehrfache Bedeutung dieses Begriffs).
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
6
persistence.xml I
<?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_2_0.xsd"
version="2.0">
<persistence-unit name="bankexample" transaction-type="RESOURCE_LOCAL">
… … Optionen … …
</persistence-unit>
</persistence>
Name des Persistenzkontextes
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
Java-SEUmgebung
7
persistence.xml II
<description>Ein einfaches Beispiel fuer 1 oder 2 Klassen</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>de.htw_berlin.f4.kbe.jpa.Person</class>
<properties>
<!-- JDBC properties -->
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost/bankexample" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver" />
<!-- Hibernate properties -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
Siehe u.a.
http://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/configuration.html
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
8
persistence.xml III - Erläuterungen
• Die Datei persistence.xml ist die zentrale Konfigurationsdatei.
• Mit Properties werden die Parameter den einzelnen Komponenten
zugeordnet.
• Wie beim nativen Hibernate gibt es SQL-Dialekte:
http://javamanikandan.blogspot.in/2014/05/sql-dialects-inhibernate.html
•
Die Hibernate-Property hibernate.hbm2ddl.auto steuert das
automatische Erzeugen und Vernichten der Tabellen in der
Datenbank, folgende Werte sind möglich:
– validate: nur Prüfen des vorhandenen Schemas
– update: Aktualisieren des vorhandenen Schemas
– create: Vollständiges Erzeugen des Schemas zum Beginn
– create-drop: create und nach dem Lauf Löschen des Schemas
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
9
Ort für persistence.xml I
|
pom.xml
+---src
|
+---main
|
|
+---java
Mit Hilfe von maven wird
|
|
|
\---de
die Datei an die richtige
|
|
|
\---htw_berlin
Stelle kopiert.
|
|
|
\---f4
|
|
|
\---kbe
(Sie muss im jar-File im
|
|
|
\---jpa
META-INF-Bereich sein)
|
|
|
App.java
|
|
|
Person.java
|
|
|
\---target
|
|
\---resources
+---classes
|
|
\---META-INF
|
|
|
|
persistence.xml
|
+---de
|
|
\---htw_berlin
|
|
\---f4
|
|
\---kbe
So muss bei netbeans der
|
|
\---jpa
SRC-Baum aussehen.
|
|
App.class
|
|
Person.class
|
|
|
\---META-INF
|
persistence.xml
10
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
Ort für persistence.xml II - netbeans
Die Datei und der Ordner
META-INF können über
Filesystem erzeugt werden
oder nach CTRL_n:
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
11
Das Hauptprogramm I - Schema
private void runner() {
...createFactory("bankexample");
EntityManager em= emf.createEntityManager();
em.getTransaction().begin();
… … …
Alle Aktivitäten
… … …
em.getTransaction().commit();
em.close();
emf.close();
}
Wenn keine Daten verändert werden, z.B. mit Selects, dann
kann die Klammerung in einer Transaktion fortfallen.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
12
Das Hauptprogramm II
private void runner() {
createFactory("bankexample");
EntityManager em= emf.createEntityManager();
Person person;
em.getTransaction().begin();
person= new Person("Heidi","Musterfrau");
System.out.println(person);
em.persist(person);
System.out.println(person);
System.out.println("Heidi ist gespeichert? --> "+em.contains(person));
person= new Person("Paul","MusterMann");
em.persist(person);
System.out.println(person);
person= new Person("Erika","Rödenhufer");
em.persist(person);
System.out.println(person);
em.getTransaction().commit();
em.close();
emf.close();
}
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
13
Das Hauptprogramm III - createFactory()
public class App {
EntityManagerFactory emf;
private void setEntityManagerFactory(String persistenceUnitName,
Map properties) {
… …
emf= provider.createEntityManagerFactory(persistenceUnitName,
properties);
}
private void createFactory(String persistenceUnit) {
setEntityManagerFactory(persistenceUnit,null);
}
public static void main( String[] args ) {
(new App()).runner();
}
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
14
Output des ersten Laufs
(01)
(02)
(03)
(04)
(05)
(06)
(07)
(08)
(09)
(10)
(11)
(12)
Hibernate: drop table if exists Person
Hibernate: create table Person (id bigint not null auto_increment,
firstName varchar(255), lastName varchar(255),
primary key (id)) ENGINE=InnoDB
####---Id=null: Heidi Musterfrau
Hibernate: insert into Person (firstName, lastName) values (?, ?)
####---Id=1: Heidi Musterfrau
Heidi ist gespeichert? --> true
Hibernate: insert into Person (firstName, lastName) values (?, ?)
####---Id=2: Paul MusterMann
Hibernate: insert into Person (firstName, lastName) values (?, ?)
####---Id=3: Erika Rödenhufer
In Zeile (05) ist die ID noch nicht bestimmt, erst nach dem
persist()-Aufruf.
Die Zeilen mit "Hibernate:" sind die an die Datenbank gesendeten
SQL-Statements.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
15
Datenbank "bankexample"
Nun schauen wir uns das generierte Schema mit den
gespeicherten Werten an.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
16
Warnung wegbekommen I
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider
[org.hibernate.ejb.HibernatePersistence];
use [org.hibernate.jpa.HibernatePersistenceProvider]
private void setEntityManagerFactory(String persistenceUnitName, Map properties) {
emf= null;
PersistenceProvider fallBackProvider= null;
List<PersistenceProvider> providers = PersistenceProviderResolverHolder
.getPersistenceProviderResolver().getPersistenceProviders();
for(PersistenceProvider provider : providers) {
if(provider instanceof org.hibernate.ejb.HibernatePersistence) {
fallBackProvider= provider;
System.out.println("#### "+provider+" ++++ skip");
continue;
}
System.out.println("#### "+provider);
emf= provider.createEntityManagerFactory(persistenceUnitName, properties);
if(emf!=null) {
break;
}
}
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
17
Warnung wegbekommen II
if(emf==null) {
if(fallBackProvider==null) {
throw new RuntimeException(„...");
}
emf= fallBackProvider.createEntityManagerFactory
(persistenceUnitName,properties);
}
}
Output:
#### org.hibernate.ejb.HibernatePersistence@6d311334 ++++ skip
#### org.hibernate.jpa.HibernatePersistenceProvider@682a0b20
Es gibt also zwei Provider, wobei der nicht zu benutzende zuerst
angeboten wird – wir nehmen den zweiten und die Warnung ist weg.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
18
Optionen angeben
private void createFactoryWithOptions(String persistenceUnit) {
Map<String, Object> configOverrides= new HashMap<>();
configOverrides.put("hibernate.hbm2ddl.auto","create-drop");
setEntityManagerFactory(persistenceUnit,configOverrides);
}
Beim Erzeugen der Factory können noch Werte für Properties
in Form einer HashMap angegeben werden, hier wird der Wert für
hibernate.hbm2ddl.auto auf create-drop gesetzt.
Statt createFactory() wird dann createFactoryWithOptions() benutzt.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
19
Alternativer ID-Generator I
@Id
@GeneratedValue(strategy= GenerationType.TABLE)
private Long id;
Es werden nun zwei Tabellen zum Verwalten der vergebenen ID-Werte
angelegt und von Hibernate benutzt – dies geht bei allen Datenbanken.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
20
Alternativer ID-Generator II
@Id
@GeneratedValue(strategy= GenerationType.TABLE,
generator= "personGenerator")
@TableGenerator(
name= "personGenerator",
table= "ID_GEN",
pkColumnName= "GEN_KEY",
valueColumnName= "GEN_VALUE",
pkColumnValue= "PERSON_ID",
AllocationSize= 10
)
private Long id;
Die Tabelle für die ID-Verwaltung kann explizit benannt und samt allen
Spalten definiert werden.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
21
Selbst verwaltete IDs I
@Entity public class Person implements Serializable {
private String id;
private String firstName;
private String lastName;
public Person() {
this.id= UUID.randomUUID().toString();
}
public Person(String firstName, String lastName) {
this();
this.firstName= firstName;
this.lastName= lastName;
}
Zugriff auf ID nur
@Id
über Getter/Setter
public String getId() {
return id;
}
Es muss nun auch
public void setId(String id) {
this.id= id;
ein Setter für ID
}
vorhanden sein.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
22
Selbst verwaltete IDs II
So sehen dann die generierten IDs aus.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
23
Lesen eines Objekts
em.getTransaction().begin();
person= new Person("Heidi", "Musterfrau");
em.persist(person);
String pKey= person.getId();
System.out.println(person);
person= new Person("Paul", "MusterMann");
em.persist(person);
System.out.println(person);
person= new Person("Erika", "Rödenhufer");
em.persist(person);
System.out.println(person);
person= em.find(Person.class, pKey);
System.out.println(person);
em.getTransaction().commit();
####---Id=d121cadd-c220-49a7-bc1b-6230a489452a:
####---Id=9678a802-f760-44c4-847d-94f0088ec5ae:
####---Id=68482017-8b0f-481b-bbb9-5a0405345fd7:
####---Id=d121cadd-c220-49a7-bc1b-6230a489452a:
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
Heidi Musterfrau
Paul MusterMann
Erika Rödenhufer
Heidi Musterfrau
24
Variation der Datentypen I
@Entity public class Person implements Serializable {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(nullable=true, length= 20)
private String firstName;
@Column(name="name", length= 20)
private String lastName;
@Temporal(TemporalType.DATE)
private Date birthday;
@Temporal(TemporalType.TIME)
private Date birthtime;
@Transient private Date adminDate;
@Lob char[] mark;
@Enumerated(EnumType.ORDINAL)
private Sex sex;
@Enumerated(EnumType.STRING)
private Salutation salutation;
@Column(precision= 10, scale= 2)
private BigDecimal purse;
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
25
Variation der Datentypen II
public Person(String firstName, String lastName, String birthday) {
DateFormat format= new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
this.firstName= firstName;
this.lastName= lastName;
try {
this.birthday= format.parse(birthday);
this.birthtime= format.parse(birthday);
} catch (ParseException e) {
throw new IllegalArgumentException("Wrong Date format");
}
}
Der Konstruktor muss nun etwas anders aussehen.
Hier wie mit Zeitformaten umgegangen werden kann.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
26
Enums und das Hauptprogramm
public enum Sex {
WOMAN, MAN
}
public enum Salutation {
Ms, Mr, Dr, Prof
}
char[] abc= {'a','b','c'};
createFactory("bankexample");
EntityManager em= emf.createEntityManager();
Person person;
… … …
person= new Person("Heidi", "Musterfrau","02.10.1970 18:13:10");
em.persist(person);
person.setSex(Sex.WOMAN);
person.setSalutation(Salutation.Dr);
person.setMark(abc);
person.setPurse(new BigDecimal("12.5"));
Long pKey= person.getId();
System.out.println(person);
person= em.find(Person.class, pKey);
System.out.println(person);
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
27
Datenbank
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
28
1:1-Relation unidirektional I
Person
Address
1
Inverse Seite
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
1
Besitzende Seite
Ebene der
Objekte
Ebene der
Tabellen
29
1:1-Relation unidirektional II
@Entity public class Person implements Serializable {
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
//@OneToOne
@OneToOne(cascade= CascadeType.ALL, orphanRemoval= true)
@JoinColumn(name= "myAddress", nullable= true)
private Address address;
JoinColumn ist die Spalte
… Getter/Setter …
mit dem Fremdschlüssel und
charakterisiert die besitzende
@Entity public class Address implements Serializable{
Seite
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String city;
private String street;
private int houseNumber;
… Getter/Setter …
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
30
1:1-Relation unidirektional III
Ohne Kaskadieren
em.getTransaction().begin();
muss das Address-Objekt
address= new Address("Berlin","Gustavzeile",3);
explizit gespeichert werden
//em.persist(address);
person= new Person("Heidi", "Musterfrau",address);
em.persist(person);
System.out.println(person);
address= new Address("Fürstenwalde","Karl-May-Allee",23);
person= new Person("Gudrun", "von Oiouten",address);
em.persist(person);
System.out.println(person);
person.setAddress(null);
//em.detach(person);
Ohne nullable= true
em.remove(person);
ergibt dies eine wenig
em.getTransaction().commit()
aussagende Fehlermeldung
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
31
1:1-Relation unidirektional IV - Bemerkungen
• Wenn bei der besitzenden Klasse (dort, wo das Join-Attribut sich
befindet) nur ein @OneToOne steht, dann müssen alle beteiligten
•
•
•
•
Objekte mit em.persist() gespeichert werden.
Wenn das Kaskadierden mit @OneToOne(cascade=CascadeType.ALL)
eingeschaltet ist, dann werden alle mit Referenzen verbundenen Entities
in der Datenbank gespeichert.
Mit dem Parameter orphanRemoval= true werden nicht per Referenz
verbundene Entities auch in der Datenbank gelöscht.
Das Setzen der Adresse mit null und anschließenden Löschen mit
em.remove(person) führt ansonsten zu einem Waisen.
Mit em.remove() wird das Objekt in der Datenbank gelöscht, mit
em.detach() wird es nur dem Programm entzogen, verbleibt aber in der
Datenbank.
Die beiden Operationen em.remove() und em.detach() betreffen nur
das JPA, nicht die Objekte im RAM des Programms. Diese werden ganz
normal mit dem Garbage-Collector entfernt.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
32
1:1-Relation unidirektional V - Schemata
Besitzer-Seite
JoinColumn mit
Originalnamen
JoinColumn mit
geänderten Namen
Inverse Seite
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
33
1:1-Relation bidirektional I
Person
Address
1
Inverse Seite
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
1
Besitzende Seite
Ebene der
Objekte
Ebene der
Tabellen
34
1:1-Relation bidirektional II
@Entity public class Person implements Serializable {
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
@OneToOne(cascade= CascadeType.ALL)
Besitzende Seite
@JoinColumn(name= "address")
private Address address;
@Entity public class Address implements Serializable {
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String city;
private String street;
private int houseNumber;
Inverse Seite
@OneToOne(mappedBy= "address")
private Person person;
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
35
1:1-Relation bidirektional III
em.getTransaction().begin();
address= new Address("Berlin","Gustavzeile",3);
person= new Person("Heidi", "Musterfrau",address);
address.setPerson(person);
em.persist(person);
System.out.println(person);
address= new Address("Fürstenwalde","Karl-May-Allee",23);
person= new Person("Gudrun", "von Oiouten",address);
address.setPerson(person);
em.persist(person);
System.out.println(person);
em.getTransaction().commit();
Bidirektional bezieht sich auf die Zeigerstruktur, d.h. auf beiden
Seiten muss es jeweils ein Attribut in der Klasse geben, in dem auf
das jeweilige andere Objekt verwiesen wird.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
36
1:1-Relation bidirektional IV - Schemata
Klasse Person
Klasse Address
Aufgrund der Relationen ändert sich an der Tabellenstruktur im Vergleich
zu unidirektionalen Beziehung nichts(!).
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
37
1:N-Relation unidirektional I
Person
Address
1
1
Account
1
1..*
Die 1:N-Relation wird
durch eine eigene
Tabelle realisiert.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
Ebene der
Objekte
Ebene der
Tabellen
38
1:N-Relation unidirektional II
@Entity public class Account implements Serializable{
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private long number;
private double bankBalance;
public Account() {}
public Account(long number, double bankBalance) {
this.number= number; this.bankBalance= bankBalance;
}
@Entity public class Person implements Serializable {
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String firstName; private String lastName;
@OneToOne(cascade= CascadeType.ALL)
@JoinColumn(name= "address")
private Address address;
@OneToMany(cascade= CascadeType.ALL)
private Set<Account> accounts;
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
Ebene der
Objekte:
Set
39
1:N-Relation unidirektional III - Hauptprogramm
em.getTransaction().begin();
address= new Address("Berlin","Gustavzeile",3);
person= new Person("Heidi", "Musterfrau",address);
address.setPerson(person);
em.persist(person);
account= new Account(42,0.0);
Zwei Konten
person.getAccounts().add(account);
werden einaccount= new Account(100,7450.80);
gerichtet
person.getAccounts().add(account);
address= new Address("Fürstenwalde","Karl-May-Allee",23);
person= new Person("Gudrun", "von Oiouten",address);
address.setPerson(person);
em.persist(person);
Ein Konto
account= new Account(5678,0.0);
wird einperson.getAccounts().add(account);
gerichtet
em.getTransaction().commit();
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
40
1:N-Relation unidirektional IV - Schemata
Klasse Person
Klasse Account
Tabelle person_account
Diese Tabelle realisiert
die 1:N-Beziehung.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
41
1:N-Relation unidirektional V - Tabelleninhalte
Klasse Person
Klasse Account
Tabelle person_account
Heidi hat zwei Konten,
während Gudrun nur eines hat.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
42
1:N-Relation bidirektional I
Person
Address
1
Account
1
1
Inverse Seite
1..*
Besitzende Seite
Die 1:N-Relation wird
nun ohne extra Tabelle
mit einem Fremdschlüssel
realisiert.
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
Ebene der
Objekte
Ebene der
Tabellen
43
1:N-Relation bidirektional II
@Entity public class Account implements Serializable{
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private long number;
private double bankBalance;
@ManyToOne(optional= false)
@JoinColumn(name= "person",nullable= false)
private Person person;
@Entity public class Person implements Serializable {
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String firstName; private String lastName;
@OneToOne(cascade= CascadeType.ALL)
@JoinColumn(name= "address")
private Address address;
@OneToMany(mappedBy= "person",cascade= CascadeType.ALL,
orphanRemoval= true)
private Set<Account> accounts;
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
44
1:N-Relation bidirektional III - Hauptprogramm
em.getTransaction().begin();
address= new Address("Berlin","Gustavzeile",3);
person= new Person("Heidi", "Musterfrau",address);
address.setPerson(person);
em.persist(person);
account= new Account(42,0.0);
person.getAccounts().add(account);
account.setPerson(person);
account= new Account(100,7450.80);
Rückverkettungen
person.getAccounts().add(account);
account.setPerson(person);
address= new Address("Fürstenwalde","Karl-May-Allee",23);
person= new Person("Gudrun", "von Oiouten",address);
address.setPerson(person);
em.persist(person);
account= new Account(5678,0.0);
person.getAccounts().add(account);
account.setPerson(person);
Rückverkettung
em.getTransaction().commit();
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
45
1:N-Relation bidirektional IV - Schemata
Klasse Person
Klasse Account
Tabelle Person
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
Tabelle Account
46
Nach dieser Anstrengung etwas Entspannung...
Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1
47
Herunterladen