JPA - Java Persistence API

6,036 views
5,879 views

Published on

JPA as Tools for an Object Oriented Domain Modell using Hibernate as JPA Vendor. Presentation was held on customer site in Berlin and transmitted to the Lünen Office.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,036
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
202
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

JPA - Java Persistence API

  1. 1. JPA - Java Persistence API Thomas Wöhlke ObjectCode GmbH 12.03.2009
  2. 2. JPA: Agenda © 2009 ObjectCode GmbH
  3. 3. Domain Object Model © 2009 ObjectCode GmbH
  4. 4. Object-Relational Mapping <ul><li>Analogie: OO  RDB </li></ul><ul><li>Klasse  Tabelle </li></ul><ul><li>Objekt  Zeile </li></ul><ul><li>Variable  Spalte </li></ul><ul><li>Wert  Feld </li></ul><ul><li>Domain Object Modell = ERD ? </li></ul>© 2009 ObjectCode GmbH
  5. 5. O/R Impedance Mismatch © 2009 ObjectCode GmbH
  6. 6. O/R Impedance Mismatch © 2009 ObjectCode GmbH
  7. 7. Domain Object Model: GLE © 2009 ObjectCode GmbH
  8. 8. ... und die Physik? <ul><li>v(Harddisk) << v(RAM) </li></ul><ul><li>CPU 99% idle </li></ul><ul><li>Process 99% IO_WAIT </li></ul><ul><li>Page Impressions  SQL-Requests? </li></ul>© 2009 ObjectCode GmbH
  9. 9. Anno Domini 2004... © 2009 ObjectCode GmbH © 2004-2005 TheServerside.com
  10. 10. Hibernate <ul><li>Mapping von POJO‘s: </li></ul><ul><li>Java Bean API </li></ul><ul><li>Collection API (Generics) </li></ul><ul><li>Mapping: XML oder Hibernate-Annotations </li></ul><ul><li>Hibernate ist ein JPA-Vendor: </li></ul><ul><li>Hibernate-Core </li></ul><ul><li>Hibernate-Annotations </li></ul><ul><li>Hibernate Entity Manager </li></ul>© 2009 ObjectCode GmbH
  11. 11. Von Hibernate nach JPA © 2009 ObjectCode GmbH
  12. 12. JPA im JEE-Stack © 2009 ObjectCode GmbH
  13. 13. persistence.xml (Java EE) <ul><li><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> </li></ul><ul><li><persistence xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot; </li></ul><ul><li>xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; </li></ul><ul><li>xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot; </li></ul><ul><li>version=&quot;1.0&quot;> </li></ul><ul><li><persistence-unit name=&quot;JPM_DB&quot;> </li></ul><ul><li><provider>org.hibernate.ejb.HibernatePersistence</provider> </li></ul><ul><li><jta-data-source>java:/JpmDS</jta-data-source> </li></ul><ul><li><properties> </li></ul><ul><li><property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create-drop&quot;/> </li></ul><ul><li><property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> </li></ul><ul><li><!-- These are the default for JBoss EJB3, but not for HEM: --> </li></ul><ul><li><property name=&quot;hibernate.cache.provider_class&quot; value=&quot;org.hibernate.cache.HashtableCacheProvider&quot;/> </li></ul><ul><li><property name=&quot;hibernate.transaction.manager_lookup_class&quot; </li></ul><ul><li>value=&quot;org.hibernate.transaction.JBossTransactionManagerLookup&quot;/> </li></ul><ul><li></properties> </li></ul><ul><li></persistence-unit> </li></ul><ul><li></persistence> </li></ul>© 2009 ObjectCode GmbH
  14. 14. persistence.xml (Java SE) <ul><li><?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> </li></ul><ul><li><persistence xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot; </li></ul><ul><li>xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; </li></ul><ul><li>xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot; </li></ul><ul><li>version=&quot;1.0&quot;> </li></ul><ul><li><persistence-unit name=&quot;JPM_DB&quot;> </li></ul><ul><li><provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.woehlke.projecteering.kernel.calendar.pao.Day</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.minutes.pao.Event</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.minutes.pao.Minutes</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.minutes.pao.MinutesItem</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.projects.pao.Project</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.projects.pao.ProjectCategory</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.timerecording.pao.TimeRecordingItem</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.userrights.pao.Company</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.userrights.pao.Team</class> </li></ul><ul><li><class>org.woehlke.projecteering.kernel.userrights.pao.User</class> </li></ul><ul><li><exclude-unlisted-classes>true</exclude-unlisted-classes> </li></ul><ul><li><properties> </li></ul><ul><li><property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create-drop&quot;/> </li></ul><ul><li><property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> </li></ul><ul><li><property name=&quot;hibernate.generate_statistics&quot; value=&quot;true&quot;/> </li></ul><ul><li><property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/> </li></ul><ul><ul><li><property name=&quot;hibernate.connection.driver_class&quot; value=&quot;com.mysql.jdbc.Driver&quot;/> </li></ul></ul><ul><li><property name=&quot;hibernate.connection.username&quot; value=&quot;jpm&quot;/> </li></ul><ul><li><property name=&quot;hibernate.connection.password&quot; value=&quot;jpmpwd&quot;/> </li></ul><ul><li><property name=&quot;hibernate.connection.url&quot; value=&quot;jdbc:mysql://localhost:3306/jpm&quot;/> </li></ul><ul><li><property name=&quot;hibernate.dialect&quot; value=&quot;org.hibernate.dialect.MySQLDialect&quot;/> </li></ul><ul><li></properties> </li></ul><ul><li></persistence-unit> </li></ul><ul><li></persistence> </li></ul>© 2009 ObjectCode GmbH
  15. 15. Mapping der Klassen 1 <ul><li>public class Customer extends Person { </li></ul><ul><li>@OneToMany(mappedBy=“purchaser”) Set<Order> orders = </li></ul><ul><li>new HashSet<Order>(); </li></ul><ul><li>protected Customer() { } // for loading from db </li></ul><ul><li>public Customer(String fname, String lname) { </li></ul><ul><li>super(fname, lname); </li></ul><ul><li>} </li></ul><ul><li>public void addOrder(Order o) { orders.add(o); } </li></ul><ul><li>public Set<Order> getOrders() { return orders; } </li></ul><ul><li>} </li></ul>© 2009 ObjectCode GmbH
  16. 16. Mapping der Klassen 2 <ul><li>@Entity </li></ul><ul><li>@Table(name=“PRODUCTS”) </li></ul><ul><li>public class Product { </li></ul><ul><li>@Id @GeneratedValue </li></ul><ul><li>@Column(name=“PRODUCT_PK”) </li></ul><ul><li>long id; </li></ul><ul><li>@Version int oplock; // column defaults to “OPLOCK” </li></ul><ul><li>String name; // column defaults to “NAME” </li></ul><ul><li>@ManyToOne </li></ul><ul><li>@JoinColumn(name=“SUPP_FK”, referencedColumnName=“SUPP_PK”) </li></ul><ul><li>Supplier supplier; </li></ul><ul><li>... </li></ul><ul><li>} </li></ul>© 2009 ObjectCode GmbH
  17. 17. Mapping der Assoziationen <ul><li>Kardinalität: </li></ul><ul><li>1:1  OneToOne </li></ul><ul><li>1:n  OneToMany </li></ul><ul><li>n:m  ManyToMany </li></ul><ul><li>Richtung: </li></ul><ul><li>1:n -> OneToMany </li></ul><ul><li>N:1 <- ManyToOne </li></ul><ul><li>Sichtbarkeit: </li></ul><ul><li>Unidirektional -> </li></ul><ul><li>Bidirektional <-> </li></ul>© 2009 ObjectCode GmbH
  18. 18. Mapping der Vererbung <ul><li>Eine Tabelle pro Klassen-Hierarchie </li></ul><ul><li>Eine Tabelle pro konkrete Klasse </li></ul><ul><li>Eine Tabelle pro Subklasse </li></ul><ul><li>Non-Entity Vererbung </li></ul><ul><li>Keine Vererbung: Embbeding </li></ul>© 2009 ObjectCode GmbH
  19. 19. Mapping der Vererbung? © 2009 ObjectCode GmbH
  20. 20. Einsatz von JPA im JBoss/EJB3 <ul><li>@Stateless </li></ul><ul><li>public class MinutesItemDao extends BaseDao<MinutesItem> implements IMinutesItemDao { </li></ul><ul><li>@PersistenceContext(unitName = &quot;JPM_DB&quot; ) </li></ul><ul><li>private EntityManager entityManager; </li></ul><ul><li>public MinutesItem findById(Long id) { </li></ul><ul><li>return entityManager.find(MinutesItem.class,id); </li></ul><ul><li>} </li></ul><ul><li>public EntityManager getEntityManager() { </li></ul><ul><li>return entityManager; </li></ul><ul><li>} </li></ul><ul><li>public void setEntityManager(EntityManager entityManager) { </li></ul><ul><li>this.entityManager = entityManager; </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>© 2009 ObjectCode GmbH
  21. 21. Einsatz von JPA in Spring/Tomcat <ul><li>@Transactional </li></ul><ul><li>public class MinutesDao extends BaseDao<Minutes> implements IMinutesDao { </li></ul><ul><li>public Minutes findById(Long id) { </li></ul><ul><li>return jpaTemplate.find(Minutes.class,id); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>© 2009 ObjectCode GmbH
  22. 22. EJB-QL <ul><li>Query q = em.createQuery(“select c from Customer c where c.firstName = :fname order by c.lastName”); </li></ul><ul><li>q.setParameter(“fname”, “Joe”); </li></ul><ul><li>q.setFirstResult(20); </li></ul><ul><li>q.setMaxResults(10); </li></ul><ul><li>List<Customer> customers = (List<Customer>) q.getResultList() ; </li></ul><ul><li>// all orders, as a named query </li></ul><ul><li>@Entity </li></ul><ul><li>@NamedQuery(name=“Order:findAllOrders”, </li></ul><ul><li>query=“select o from Order o”); </li></ul><ul><li>public class Order { ... } </li></ul><ul><li>Query q = em.createNamedQuery(“Order:findAllOrders”); </li></ul>© 2009 ObjectCode GmbH
  23. 23. Lebenszyklus Persistente Objekte <ul><li>Neu, transient (@Id id == null) </li></ul><ul><li>Persistent (@Id id != null) </li></ul><ul><li>Detached: </li></ul><ul><ul><li>Wie persistent (@Id id!= null) </li></ul></ul><ul><ul><li>Jedoch ausserhalb des EntityManager Kontext </li></ul></ul><ul><ul><li>Lazy Loading nicht möglich! </li></ul></ul><ul><ul><li>Änderungen in DB sichern mit merge </li></ul></ul>© 2009 ObjectCode GmbH
  24. 24. EJB-QL <ul><li>// all people, via a custom SQL statement </li></ul><ul><li>Query q = em.createNativeQuery(“SELECT ID, VERSION, SUBCLASS, FIRSTNAME, LASTNAME FROM PERSON”, Person.class); </li></ul><ul><li>List<Person> people = (List<Person>) q.getResultList() ; </li></ul><ul><li>// single-result aggregate: average order total price </li></ul><ul><li>Query q = em.createQuery( “select avg(i.price) from Item i” ); </li></ul><ul><li>Number avgPrice = (Number) q.getSingleResult(); </li></ul><ul><li>// traverse to-many relations </li></ul><ul><li>Query q = em.createQuery( “ select o from Order o left join o.items li where li.price > :price ”); </li></ul><ul><li>q.setParameter(“price”, 1000); </li></ul><ul><li>List<Order> orders = (List<Order>) q.getResultList(); </li></ul>© 2009 ObjectCode GmbH
  25. 25. Lazy Loading <ul><li>Supplier s = order.getItem().getProduct().getSupplier(); </li></ul><ul><li>Bei Aufruf eines Getters wird Objekt aus DB-Zeile nachgeladen. </li></ul><ul><li>Ohne Lazy Loading muss komplettes Objekt-Netz geladen werden. </li></ul><ul><li>Struktur des Objekt-Netzes variiert je nach Web-View </li></ul>© 2009 ObjectCode GmbH
  26. 26. DAO und „Unit of Work“ © 2009 ObjectCode GmbH
  27. 27. Ausblick: Seam <ul><li>Kern-Entwickler von Hibernate sind nun im Seam-Projekt </li></ul><ul><li>O/R-Mapping von EJB3/JPA auch für die Webapplikation </li></ul><ul><li>OO im Datenbankbackend durch ORM </li></ul><ul><li>OO im Webfrontend durch JSF </li></ul><ul><li>Im Conversation-Scope ist Lazy-Loading möglich. </li></ul><ul><li>Detached Objects können für die Webview verwendet werden: Kein DTO-Antipattern </li></ul>© 2009 ObjectCode GmbH
  28. 28. <ul><li>RTFM: http://www.hibernate.org/ </li></ul><ul><li>O‘Reilly: Enterprise JavaBeans 3.0 </li></ul><ul><li>Manning: EJB3 in Action </li></ul><ul><li>Manning: Hibernate in Action </li></ul>Literatur © 2009 ObjectCode GmbH
  29. 29. FRAGEN? Fragen! <ul><li>... Vielen Dank </li></ul><ul><li>für die Aufmerksamkeit </li></ul>© 2009 ObjectCode GmbH

×