JPA - Java Persistence API

29
JPA - Java Persistence API Thomas Wöhlke ObjectCode GmbH 12.03.2009

Transcript of JPA - Java Persistence API

Page 1: JPA - Java Persistence API

JPA - Java Persistence API

Thomas WöhlkeObjectCode GmbH

12.03.2009

Page 2: JPA - Java Persistence API

JPA: Agenda

© 2009 ObjectCode GmbH

Page 3: JPA - Java Persistence API

Domain Object Model

© 2009 ObjectCode GmbH

Page 4: JPA - Java Persistence API

Object-Relational MappingAnalogie: OO RDB

1. Klasse Tabelle2. Objekt Zeile3. Variable Spalte4. Wert Feld

Domain Object Modell = ERD ?

© 2009 ObjectCode GmbH

Page 5: JPA - Java Persistence API

O/R Impedance Mismatch

© 2009 ObjectCode GmbH

Page 6: JPA - Java Persistence API

O/R Impedance Mismatch

© 2009 ObjectCode GmbH

Page 7: JPA - Java Persistence API

Domain Object Model: GLE

© 2009 ObjectCode GmbH

Page 8: JPA - Java Persistence API

... und die Physik?

• v(Harddisk) << v(RAM)• CPU 99% idle• Process 99% IO_WAIT• Page Impressions SQL-Requests?

© 2009 ObjectCode GmbH

Page 9: JPA - Java Persistence API

Anno Domini 2004...

© 2009 ObjectCode GmbH© 2004-2005 TheServerside.com

Page 10: JPA - Java Persistence API

HibernateMapping von POJO‘s:1. Java Bean API2. Collection API (Generics)3. Mapping:

XML oder Hibernate-Annotations

Hibernate ist ein JPA-Vendor:1. Hibernate-Core2. Hibernate-Annotations3. Hibernate Entity Manager

© 2009 ObjectCode GmbH

Page 11: JPA - Java Persistence API

Von Hibernate nach JPA

© 2009 ObjectCode GmbH

Page 12: JPA - Java Persistence API

JPA im JEE-Stack

© 2009 ObjectCode GmbH

Page 13: JPA - Java Persistence API

persistence.xml (Java EE)<?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_1_0.xsd" version="1.0"> <persistence-unit name="JPM_DB"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/JpmDS</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="create-drop"/> <property name="hibernate.show_sql" value="true"/> <!-- These are the default for JBoss EJB3, but not for HEM: --> <property name="hibernate.cache.provider_class"

value="org.hibernate.cache.HashtableCacheProvider"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/> </properties> </persistence-unit></persistence>

© 2009 ObjectCode GmbH

Page 14: JPA - Java Persistence API

persistence.xml (Java SE)<?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_1_0.xsd" version="1.0">

<persistence-unit name="JPM_DB"> <provider>org.hibernate.ejb.HibernatePersistence</provider>

<class>org.woehlke.projecteering.kernel.calendar.pao.Day</class> <class>org.woehlke.projecteering.kernel.minutes.pao.Event</class> <class>org.woehlke.projecteering.kernel.minutes.pao.Minutes</class> <class>org.woehlke.projecteering.kernel.minutes.pao.MinutesItem</class> <class>org.woehlke.projecteering.kernel.projects.pao.Project</class> <class>org.woehlke.projecteering.kernel.projects.pao.ProjectCategory</class> <class>org.woehlke.projecteering.kernel.timerecording.pao.TimeRecordingItem</class> <class>org.woehlke.projecteering.kernel.userrights.pao.Company</class> <class>org.woehlke.projecteering.kernel.userrights.pao.Team</class> <class>org.woehlke.projecteering.kernel.userrights.pao.User</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.hbm2ddl.auto" value="create-drop"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.generate_statistics" value="true"/> <property name="hibernate.show_sql" value="true"/>

<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.username" value="jpm"/> <property name="hibernate.connection.password" value="jpmpwd"/> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpm"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/></properties> </persistence-unit></persistence>

© 2009 ObjectCode GmbH

Page 15: JPA - Java Persistence API

Mapping der Klassen 1public class Customer extends Person { @OneToMany(mappedBy=“purchaser”) Set<Order> orders = new HashSet<Order>(); protected Customer() { } // for loading from db public Customer(String fname, String lname) { super(fname, lname); } public void addOrder(Order o) { orders.add(o); } public Set<Order> getOrders() { return orders; }}

© 2009 ObjectCode GmbH

Page 16: JPA - Java Persistence API

Mapping der Klassen 2@Entity@Table(name=“PRODUCTS”)public class Product { @Id @GeneratedValue @Column(name=“PRODUCT_PK”) long id; @Version int oplock; // column defaults to “OPLOCK” String name; // column defaults to “NAME”

@ManyToOne @JoinColumn(name=“SUPP_FK”, referencedColumnName=“SUPP_PK”) Supplier supplier; ...}

© 2009 ObjectCode GmbH

Page 17: JPA - Java Persistence API

Mapping der AssoziationenKardinalität:1. 1:1 OneToOne 2. 1:n OneToMany3. n:m ManyToMany

Richtung:1. 1:n -> OneToMany2. N:1 <- ManyToOne

Sichtbarkeit:1. Unidirektional ->2. Bidirektional <->

© 2009 ObjectCode GmbH

Page 18: JPA - Java Persistence API

Mapping der Vererbung

1. Eine Tabelle pro Klassen-Hierarchie2. Eine Tabelle pro konkrete Klasse3. Eine Tabelle pro Subklasse4. Non-Entity Vererbung5. Keine Vererbung: Embbeding

© 2009 ObjectCode GmbH

Page 19: JPA - Java Persistence API

Mapping der Vererbung?

© 2009 ObjectCode GmbH

Page 20: JPA - Java Persistence API

Einsatz von JPA im JBoss/EJB3@Statelesspublic class MinutesItemDao extends BaseDao<MinutesItem> implements

IMinutesItemDao {

@PersistenceContext(unitName = "JPM_DB") private EntityManager entityManager;

public MinutesItem findById(Long id) { return entityManager.find(MinutesItem.class,id); }

public EntityManager getEntityManager() { return entityManager; }

public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; }}

© 2009 ObjectCode GmbH

Page 21: JPA - Java Persistence API

Einsatz von JPA in Spring/Tomcat@Transactionalpublic class MinutesDao extends BaseDao<Minutes> implements

IMinutesDao {

public Minutes findById(Long id) { return jpaTemplate.find(Minutes.class,id); }

}

© 2009 ObjectCode GmbH

Page 22: JPA - Java Persistence API

EJB-QLQuery q = em.createQuery(“select c from Customer c where c.firstName

= :fname order by c.lastName”);q.setParameter(“fname”, “Joe”);q.setFirstResult(20);q.setMaxResults(10);List<Customer> customers = (List<Customer>) q.getResultList();

// all orders, as a named query@Entity @NamedQuery(name=“Order:findAllOrders”, query=“select o from Order o”);public class Order { ... }

Query q = em.createNamedQuery(“Order:findAllOrders”);

© 2009 ObjectCode GmbH

Page 23: JPA - Java Persistence API

Lebenszyklus Persistente Objekte

1. Neu, transient (@Id id == null)2. Persistent (@Id id != null)3. Detached:

– Wie persistent (@Id id!= null)– Jedoch ausserhalb des EntityManager Kontext– Lazy Loading nicht möglich!– Änderungen in DB sichern mit merge

© 2009 ObjectCode GmbH

Page 24: JPA - Java Persistence API

EJB-QL // all people, via a custom SQL statementQuery q = em.createNativeQuery(“SELECT ID, VERSION, SUBCLASS,

FIRSTNAME, LASTNAME FROM PERSON”, Person.class);List<Person> people = (List<Person>) q.getResultList();

// single-result aggregate: average order total price Query q = em.createQuery(“select avg(i.price) from Item i”);Number avgPrice = (Number) q.getSingleResult();

// traverse to-many relationsQuery q = em.createQuery(“select o from Order o left join o.items li where

li.price > :price”);q.setParameter(“price”, 1000);List<Order> orders = (List<Order>) q.getResultList();

© 2009 ObjectCode GmbH

Page 25: JPA - Java Persistence API

Lazy Loading• Supplier s = order.getItem().getProduct().getSupplier();• Bei Aufruf eines Getters wird Objekt aus DB-Zeile nachgeladen.• Ohne Lazy Loading muss komplettes Objekt-Netz geladen werden.• Struktur des Objekt-Netzes variiert je nach Web-View

© 2009 ObjectCode GmbH

Page 26: JPA - Java Persistence API

DAO und „Unit of Work“

© 2009 ObjectCode GmbH

Page 27: JPA - Java Persistence API

Ausblick: Seam• Kern-Entwickler von Hibernate sind nun im Seam-

Projekt• O/R-Mapping von EJB3/JPA auch für die

Webapplikation• OO im Datenbankbackend durch ORM• OO im Webfrontend durch JSF• Im Conversation-Scope ist Lazy-Loading möglich.• Detached Objects können für die Webview

verwendet werden: Kein DTO-Antipattern

© 2009 ObjectCode GmbH

Page 28: JPA - Java Persistence API

RTFM: http://www.hibernate.org/O‘Reilly: Enterprise JavaBeans 3.0Manning: EJB3 in ActionManning: Hibernate in Action

Literatur

© 2009 ObjectCode GmbH

Page 29: JPA - Java Persistence API

FRAGEN? Fragen!

... Vielen Dank für die Aufmerksamkeit

© 2009 ObjectCode GmbH