KEMBAR78
JPA - Java Persistence API | PPS
JPA - Java Persistence API Thomas Wöhlke ObjectCode GmbH 12.03.2009
JPA: Agenda © 2009 ObjectCode GmbH
Domain Object Model © 2009 ObjectCode GmbH
Object-Relational Mapping Analogie: OO    RDB Klasse     Tabelle Objekt    Zeile Variable    Spalte Wert     Feld Domain Object Modell = ERD ? © 2009 ObjectCode GmbH
O/R Impedance Mismatch © 2009 ObjectCode GmbH
O/R Impedance Mismatch © 2009 ObjectCode GmbH
Domain Object Model: GLE © 2009 ObjectCode GmbH
... und die Physik? v(Harddisk) << v(RAM) CPU 99% idle Process 99% IO_WAIT Page Impressions    SQL-Requests? © 2009 ObjectCode GmbH
Anno Domini 2004... © 2009 ObjectCode GmbH © 2004-2005 TheServerside.com
Hibernate Mapping von POJO‘s: Java Bean API Collection API (Generics) Mapping:  XML oder Hibernate-Annotations Hibernate ist ein JPA-Vendor: Hibernate-Core Hibernate-Annotations Hibernate Entity Manager © 2009 ObjectCode GmbH
Von Hibernate nach JPA © 2009 ObjectCode GmbH
JPA im JEE-Stack © 2009 ObjectCode GmbH
persistence.xml (Java EE) <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <persistence xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence  http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot; version=&quot;1.0&quot;> <persistence-unit name=&quot;JPM_DB&quot;> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/JpmDS</jta-data-source> <properties> <property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create-drop&quot;/> <property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> <!-- These are the default for JBoss EJB3, but not for HEM: --> <property name=&quot;hibernate.cache.provider_class&quot;  value=&quot;org.hibernate.cache.HashtableCacheProvider&quot;/> <property name=&quot;hibernate.transaction.manager_lookup_class&quot; value=&quot;org.hibernate.transaction.JBossTransactionManagerLookup&quot;/> </properties> </persistence-unit> </persistence> © 2009 ObjectCode GmbH
persistence.xml (Java SE) <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <persistence xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot; version=&quot;1.0&quot;> <persistence-unit name=&quot;JPM_DB&quot;> <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=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create-drop&quot;/> <property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> <property name=&quot;hibernate.generate_statistics&quot; value=&quot;true&quot;/> <property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> <property name=&quot;hibernate.connection.driver_class&quot; value=&quot;com.mysql.jdbc.Driver&quot;/> <property name=&quot;hibernate.connection.username&quot; value=&quot;jpm&quot;/> <property name=&quot;hibernate.connection.password&quot; value=&quot;jpmpwd&quot;/> <property name=&quot;hibernate.connection.url&quot; value=&quot;jdbc:mysql://localhost:3306/jpm&quot;/> <property name=&quot;hibernate.dialect&quot; value=&quot;org.hibernate.dialect.MySQLDialect&quot;/> </properties> </persistence-unit> </persistence> © 2009 ObjectCode GmbH
Mapping der Klassen 1 public 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
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
Mapping der Assoziationen Kardinalität: 1:1  OneToOne  1:n  OneToMany n:m  ManyToMany Richtung: 1:n -> OneToMany N:1 <- ManyToOne Sichtbarkeit: Unidirektional -> Bidirektional <-> © 2009 ObjectCode GmbH
Mapping der Vererbung Eine Tabelle pro Klassen-Hierarchie Eine Tabelle pro konkrete Klasse Eine Tabelle pro Subklasse Non-Entity Vererbung Keine Vererbung: Embbeding © 2009 ObjectCode GmbH
Mapping der Vererbung? © 2009 ObjectCode GmbH
Einsatz von JPA im JBoss/EJB3 @Stateless public class MinutesItemDao extends BaseDao<MinutesItem> implements IMinutesItemDao { @PersistenceContext(unitName =  &quot;JPM_DB&quot; ) 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
Einsatz von JPA in Spring/Tomcat @Transactional public class MinutesDao extends BaseDao<Minutes> implements IMinutesDao { public Minutes findById(Long id) { return jpaTemplate.find(Minutes.class,id); } } © 2009 ObjectCode GmbH
EJB-QL Query 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
Lebenszyklus Persistente Objekte Neu, transient (@Id id == null) Persistent (@Id id != null) 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
EJB-QL  // all people, via a custom SQL statement Query 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 relations Query 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
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
DAO und „Unit of Work“ © 2009 ObjectCode GmbH
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
RTFM: http://www.hibernate.org/ O‘Reilly: Enterprise JavaBeans 3.0 Manning: EJB3 in Action Manning: Hibernate in Action Literatur © 2009 ObjectCode GmbH
FRAGEN? Fragen! ... Vielen Dank  für die Aufmerksamkeit © 2009 ObjectCode GmbH

JPA - Java Persistence API

  • 1.
    JPA - JavaPersistence API Thomas Wöhlke ObjectCode GmbH 12.03.2009
  • 2.
    JPA: Agenda ©2009 ObjectCode GmbH
  • 3.
    Domain Object Model© 2009 ObjectCode GmbH
  • 4.
    Object-Relational Mapping Analogie:OO  RDB Klasse  Tabelle Objekt  Zeile Variable  Spalte Wert  Feld Domain Object Modell = ERD ? © 2009 ObjectCode GmbH
  • 5.
    O/R Impedance Mismatch© 2009 ObjectCode GmbH
  • 6.
    O/R Impedance Mismatch© 2009 ObjectCode GmbH
  • 7.
    Domain Object Model:GLE © 2009 ObjectCode GmbH
  • 8.
    ... und diePhysik? v(Harddisk) << v(RAM) CPU 99% idle Process 99% IO_WAIT Page Impressions  SQL-Requests? © 2009 ObjectCode GmbH
  • 9.
    Anno Domini 2004...© 2009 ObjectCode GmbH © 2004-2005 TheServerside.com
  • 10.
    Hibernate Mapping vonPOJO‘s: Java Bean API Collection API (Generics) Mapping: XML oder Hibernate-Annotations Hibernate ist ein JPA-Vendor: Hibernate-Core Hibernate-Annotations Hibernate Entity Manager © 2009 ObjectCode GmbH
  • 11.
    Von Hibernate nachJPA © 2009 ObjectCode GmbH
  • 12.
    JPA im JEE-Stack© 2009 ObjectCode GmbH
  • 13.
    persistence.xml (Java EE)<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <persistence xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot; version=&quot;1.0&quot;> <persistence-unit name=&quot;JPM_DB&quot;> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/JpmDS</jta-data-source> <properties> <property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create-drop&quot;/> <property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> <!-- These are the default for JBoss EJB3, but not for HEM: --> <property name=&quot;hibernate.cache.provider_class&quot; value=&quot;org.hibernate.cache.HashtableCacheProvider&quot;/> <property name=&quot;hibernate.transaction.manager_lookup_class&quot; value=&quot;org.hibernate.transaction.JBossTransactionManagerLookup&quot;/> </properties> </persistence-unit> </persistence> © 2009 ObjectCode GmbH
  • 14.
    persistence.xml (Java SE)<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <persistence xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot; version=&quot;1.0&quot;> <persistence-unit name=&quot;JPM_DB&quot;> <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=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create-drop&quot;/> <property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> <property name=&quot;hibernate.generate_statistics&quot; value=&quot;true&quot;/> <property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> <property name=&quot;hibernate.connection.driver_class&quot; value=&quot;com.mysql.jdbc.Driver&quot;/> <property name=&quot;hibernate.connection.username&quot; value=&quot;jpm&quot;/> <property name=&quot;hibernate.connection.password&quot; value=&quot;jpmpwd&quot;/> <property name=&quot;hibernate.connection.url&quot; value=&quot;jdbc:mysql://localhost:3306/jpm&quot;/> <property name=&quot;hibernate.dialect&quot; value=&quot;org.hibernate.dialect.MySQLDialect&quot;/> </properties> </persistence-unit> </persistence> © 2009 ObjectCode GmbH
  • 15.
    Mapping der Klassen1 public 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
  • 16.
    Mapping der Klassen2 @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
  • 17.
    Mapping der AssoziationenKardinalität: 1:1  OneToOne 1:n  OneToMany n:m  ManyToMany Richtung: 1:n -> OneToMany N:1 <- ManyToOne Sichtbarkeit: Unidirektional -> Bidirektional <-> © 2009 ObjectCode GmbH
  • 18.
    Mapping der VererbungEine Tabelle pro Klassen-Hierarchie Eine Tabelle pro konkrete Klasse Eine Tabelle pro Subklasse Non-Entity Vererbung Keine Vererbung: Embbeding © 2009 ObjectCode GmbH
  • 19.
    Mapping der Vererbung?© 2009 ObjectCode GmbH
  • 20.
    Einsatz von JPAim JBoss/EJB3 @Stateless public class MinutesItemDao extends BaseDao<MinutesItem> implements IMinutesItemDao { @PersistenceContext(unitName = &quot;JPM_DB&quot; ) 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
  • 21.
    Einsatz von JPAin Spring/Tomcat @Transactional public class MinutesDao extends BaseDao<Minutes> implements IMinutesDao { public Minutes findById(Long id) { return jpaTemplate.find(Minutes.class,id); } } © 2009 ObjectCode GmbH
  • 22.
    EJB-QL Query 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
  • 23.
    Lebenszyklus Persistente ObjekteNeu, transient (@Id id == null) Persistent (@Id id != null) 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
  • 24.
    EJB-QL //all people, via a custom SQL statement Query 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 relations Query 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
  • 25.
    Lazy Loading Suppliers = 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
  • 26.
    DAO und „Unitof Work“ © 2009 ObjectCode GmbH
  • 27.
    Ausblick: Seam Kern-Entwicklervon 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
  • 28.
    RTFM: http://www.hibernate.org/ O‘Reilly:Enterprise JavaBeans 3.0 Manning: EJB3 in Action Manning: Hibernate in Action Literatur © 2009 ObjectCode GmbH
  • 29.
    FRAGEN? Fragen! ...Vielen Dank für die Aufmerksamkeit © 2009 ObjectCode GmbH