47
13.01.15 1 Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 Komponenten-basierte Entwicklung Teil 14: Persistenz mit Hibernate-JPA Teil 1

Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

13.01.15 1Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten-basierte Entwicklung

Teil 14: Persistenz mit Hibernate-JPATeil 1

Page 2: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 2

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.pdf

Page 3: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 3

Was macht Hibernate?

• Hibernate realisiert die JPA-Schnittstelle in der Version 2.0.Siehe: http://de.wikipedia.org/wiki/Hibernate_(Framework)

• JPA = Java Persistence APISiehe: http://de.wikipedia.org/wiki/Java_Persistence_API

Die Fehlermeldungen sind meist besser als beim nativen Hibernate,trotzdem noch grausig.

Page 4: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 4

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></dependency><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>

Es soll nur die Java-APIbenutzt werden.

Page 5: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 5

Klasse Person I

@Entitypublic 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); }

Page 6: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 6

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).

Page 7: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 7

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 Persistenz-kontextes

Java-SE-Umgebung

Page 8: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 8

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

Page 9: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 9

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-in-hibernate.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

Page 10: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 10

Ort für persistence.xml I

| pom.xml+---src| +---main| | +---java| | | \---de| | | \---htw_berlin| | | \---f4| | | \---kbe| | | \---jpa| | | App.java| | | Person.java| | | | | \---resources| | \---META-INF| | persistence.xml

\---target +---classes | | | +---de | | \---htw_berlin | | \---f4 | | \---kbe | | \---jpa | | App.class | | Person.class | | | \---META-INF | persistence.xml

So muss bei netbeans derSRC-Baum aussehen.

Mit Hilfe von maven wird die Datei an die richtigeStelle kopiert.

(Sie muss im jar-File imMETA-INF-Bereich sein)

Page 11: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 11

Ort für persistence.xml II - netbeans

Die Datei und der OrdnerMETA-INF können überFilesystem erzeugt werdenoder nach CTRL_n:

Page 12: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 12

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, dannkann die Klammerung in einer Transaktion fortfallen.

Page 13: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 13

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();}

Page 14: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 14

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(); }

Page 15: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 15

Output des ersten Laufs

(01) Hibernate: drop table if exists Person(02) Hibernate: create table Person (id bigint not null auto_increment,(03) firstName varchar(255), lastName varchar(255),(04) primary key (id)) ENGINE=InnoDB(05) ####---Id=null: Heidi Musterfrau(06) Hibernate: insert into Person (firstName, lastName) values (?, ?)(07) ####---Id=1: Heidi Musterfrau(08) Heidi ist gespeichert? --> true(09) Hibernate: insert into Person (firstName, lastName) values (?, ?)(10) ####---Id=2: Paul MusterMann(11) Hibernate: insert into Person (firstName, lastName) values (?, ?)(12) ####---Id=3: Erika Rödenhufer

In Zeile (05) ist die ID noch nicht bestimmt, erst nach dempersist()-Aufruf.Die Zeilen mit "Hibernate:" sind die an die Datenbank gesendetenSQL-Statements.

Page 16: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 16

Datenbank "bankexample"

Nun schauen wir uns das generierte Schema mit dengespeicherten Werten an.

Page 17: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 17

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; } }

Page 18: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 18

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 zuerstangeboten wird – wir nehmen den zweiten und die Warnung ist weg.

Page 19: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 19

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 Propertiesin Form einer HashMap angegeben werden, hier wird der Wert fürhibernate.hbm2ddl.auto auf create-drop gesetzt.

Statt createFactory() wird dann createFactoryWithOptions() benutzt.

Page 20: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 20

Alternativer ID-Generator I

@Id@GeneratedValue(strategy= GenerationType.TABLE)private Long id;

Es werden nun zwei Tabellen zum Verwalten der vergebenen ID-Werteangelegt und von Hibernate benutzt – dies geht bei allen Datenbanken.

Page 21: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 21

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 allenSpalten definiert werden.

Page 22: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 22

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; } @Id public String getId() { return id; } public void setId(String id) { this.id= id; }

Es muss nun auchein Setter für IDvorhanden sein.

Zugriff auf ID nurüber Getter/Setter

Page 23: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 23

Selbst verwaltete IDs II

So sehen dann die generierten IDs aus.

Page 24: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 24

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: Heidi Musterfrau####---Id=9678a802-f760-44c4-847d-94f0088ec5ae: Paul MusterMann####---Id=68482017-8b0f-481b-bbb9-5a0405345fd7: Erika Rödenhufer####---Id=d121cadd-c220-49a7-bc1b-6230a489452a: Heidi Musterfrau

Page 25: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 25

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;

Page 26: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 26

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.

Page 27: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 27

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);

Page 28: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 28

Datenbank

Page 29: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 29

1:1-Relation unidirektional I

Address Person1

Besitzende SeiteInverse Seite

1 Ebene derObjekte

Ebene derTabellen

Page 30: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 30

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; … Getter/Setter …

@Entity public class Address implements Serializable{ @Id @GeneratedValue(strategy= GenerationType.AUTO) private Long id; private String city; private String street; private int houseNumber; … Getter/Setter …

JoinColumn ist die Spaltemit dem Fremdschlüssel undcharakterisiert die besitzendeSeite

Page 31: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 31

1:1-Relation unidirektional III

em.getTransaction().begin(); address= new Address("Berlin","Gustavzeile",3); //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); em.remove(person);em.getTransaction().commit()

Ohne Kaskadierenmuss das Address-Objektexplizit gespeichert werden

Ohne nullable= trueergibt dies eine wenigaussagende Fehlermeldung

Page 32: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 32

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.

Page 33: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 33

1:1-Relation unidirektional V - Schemata

Besitzer-Seite

Inverse Seite

JoinColumn mitgeänderten Namen

JoinColumn mitOriginalnamen

Page 34: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 34

1:1-Relation bidirektional I

Address Person1 1 Ebene der

Objekte

Besitzende SeiteInverse SeiteEbene derTabellen

Page 35: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 35

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) @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; @OneToOne(mappedBy= "address") private Person person;

Besitzende Seite

Inverse Seite

Page 36: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 36

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 beidenSeiten muss es jeweils ein Attribut in der Klasse geben, in dem aufdas jeweilige andere Objekt verwiesen wird.

Page 37: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 37

1:1-Relation bidirektional IV - Schemata

Klasse Person

Klasse Address

Aufgrund der Relationen ändert sich an der Tabellenstruktur im Vergleichzu unidirektionalen Beziehung nichts(!).

Page 38: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 38

1:N-Relation unidirektional I

Address Person Account1 1..*1 1

Die 1:N-Relation wirddurch eine eigeneTabelle realisiert.

Ebene derObjekte

Ebene derTabellen

Page 39: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 39

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;

Ebene derObjekte:Set

Page 40: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 40

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); person.getAccounts().add(account); account= new Account(100,7450.80); 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); account= new Account(5678,0.0); person.getAccounts().add(account);em.getTransaction().commit();

Zwei Kontenwerden ein-gerichtet

Ein Kontowird ein-gerichtet

Page 41: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 41

1:N-Relation unidirektional IV - Schemata

Klasse Person

Klasse Account

Tabelle person_accountDiese Tabelle realisiertdie 1:N-Beziehung.

Page 42: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 42

1:N-Relation unidirektional V - Tabelleninhalte

Klasse Person

Klasse Account

Tabelle person_account

Heidi hat zwei Konten,während Gudrun nur eines hat.

Page 43: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 43

1:N-Relation bidirektional I

Address Person Account1 1..*1 1

Die 1:N-Relation wirdnun ohne extra Tabellemit einem Fremdschlüsselrealisiert.

Ebene derObjekte

Ebene derTabellen

Besitzende SeiteInverse Seite

Page 44: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 44

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;

Page 45: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 45

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); 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);em.getTransaction().commit();

Rückverkettungen

Rückverkettung

Page 46: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 46

1:N-Relation bidirektional IV - Schemata

Klasse Person

Klasse Account

Tabelle Person Tabelle Account

Page 47: Komponenten-basierte Entwicklung Teil 14: Persistenz mit ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-14/14-KBE... · Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1

Komponenten – WS 2014/15 – Teil 14/Hibernate-JPA1 47

Nach dieser Anstrengung etwas Entspannung...