Java Persistence in ActionEinsatz von JPA 2.x in Java-EE-Anwendungen          Dirk Weil | GEDOPLAN
Dirk Weil    • GEDOPLAN GmbH, Bielefeld    • Java EE seit 1998    • Konzeption und      Realisierung    • Vorträge    • Se...
ZEILEN3   Java Persistence in Action   dirk.weil@gedoplan.de
Java Persistence in EE-Anwendungen    • Basics:      – META-INF/persistence.xml referenziert Datasource                <pe...
Java Persistence in EE-Anwendungen    • The CDI way:        public class EntityManagerProducer {                          ...
Entity Manager Lifecycle    • EM-Lebensdauer                  Entity-Management-Zeit      – Entities werden detached      ...
Entity Manager Lifecycle             <h:dataTable value="#{personModel.personen}" var="person">               …           ...
Entity Manager Lifecycle    • EM-Optionen:      – Transaction-scoped      – (Extended)*                                   ...
Transaction-scoped Entity Manager    • Standard für container-managed Entity Manager      @Transactional      public class...
Transaction-scoped Entity Manager     • Start: Erste Nutzung des EM in einer TX     • Ende: TX-Ende      alle Entities wer...
Transaction-scoped Entity Manager               <h:dataTable value="#{personModel.personen}" …>     View        …         ...
Transaction-scoped Entity Manager     • Eager Loading nötig       – deklarativ      @ElementCollection(fetch = FetchType.E...
Transaction-scoped Entity Manager     • Code Browsing:       Personenverwaltung mit detached Entities                     ...
Transaction-scoped Entity Manager     • Alternative: Transaction per Request                                              ...
Transaction-scoped Entity Manager     • Transaction per Request       – mittels Servlet Filter       – mittels JSF Phase L...
Transaction-scoped Entity Manager     • Einfaches Verfahren     • Eager Loading       – ist aufwändig       – hebelt Lazy-...
Application-managed Entity Manager      • Nutzung von EntityManagerFactory      • Lifecycle wird von Anwendung bestimmt   ...
Application-managed Entity Manager     • persist, merge, remove auch ohne TX erlaubt     • Änderungen werden erst durch Co...
Request-scoped Entity Manager                        @Produces     • Request          @RequestScoped       Scope          ...
Conversation-scoped Entity Manager     • Conversational               @Produces                                    @Conver...
Conversation-scoped Entity Manager     • ABER:       – Conversation Scope ist passivating       – Objekte in ihm müssen se...
Conversation-scoped Entity Manager     • Serializable-Wrapper: @Produces @ConversationScoped public EntityManager createEn...
Conversation-scoped Entity Manager     • Serializable-Wrapper:class EMInvocationHandler implements InvocationHandler, Seri...
Conversation-scoped Entity Manager     • Serializable-Wrapper:       – Prinzip Hoffnung:         Wahrscheinlich keine Pass...
Conversation-scoped Entity Manager     • Code Browsing:       Personenverwaltung mit attached Entities                    ...
SQL-Zugriffe im Beispiel     Aktion   TX-scoped EM                                 Conv-scoped EM     Anzeige aller Person...
SQL-Zugriffe im Beispiel     Aktion   TX-scoped EM                              Conv-scoped EM     Ändern des Vornamens un...
TX- oder Conversation-scoped?     • Transaction-scoped EM         einfaches Vorgehen         speichert nur das, was expliz...
JPA 2.1 – Whats coming?     • Query-Erweiterungen       – ON: Join-Filter                select p.name, count(b)          ...
JPA 2.1 – Whats coming?      • Bulk Update/Delete für Criteria Query         CriteriaUpdate<Product> criteriaUpdate       ...
JPA 2.1 – Whats coming?      • ConstructorResult für native Queries     Query query = entityManager.createNativeQuery(    ...
JPA 2.1 – Whats coming?      • Konverter     @Converter     public class YesNoConverter implements AttributeConverter<Bool...
JPA 2.1 – Whats coming?     • CDI Injection in Entity Listener        public class CountryListener {          @Inject     ...
JPA 2.1 – Whats coming?     • Unsynchronisierter Persistence Context        @PersistenceContext(          name = "default"...
JPA 2.1 – Whats coming?     • Dynamische Erzeugung von Named Queries     • DDL Handling35                Java Persistence ...
JPA 2.1 – (bisher nur) vorgeschlagen     •   Fetch groups     •   Immutable attributes, readonly entities     •   UUID gen...
JPA 2.1 – Reicht das?     • Ja       – für neue Anwendungen       – in 90%+ der Fälle     • Aber:       – Legacy Databases...
JPA 2.1 – Reicht das?     • Legacy Databases                                                EclipseLink   Hibernate      O...
JPA 2.1 – Reicht das?     • Performance                                     EclipseLink        Hibernate   OpenJPA       R...
JPA 2.1 – Reicht das?     • Wunschliste ist nicht leer        – Vieles bereits proprietär vorhanden     • Portabilität ist...
Schön, dass Sie da waren!Di, 20:30: Java EE Day PanelMi, 16:30: Gute Zeilen, schlechte ZeilenMi, 19:45: Java on Tracks    ...
Upcoming SlideShare
Loading in …5
×

Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungen

1,221 views

Published on

Präsentation zum Vortrag von Dirk Weil (GEDOPLAN, http://www.gedoplan.de) auf der W-JAX 2012:

Der überwiegende Teil von Unternehmensanwendungen nutzt O/R-Mapper zum Zugriff auf Datenbanken. Reicht dafür der Standard JPA 2.0 oder braucht man zwingend spezielle Eigenschaften von Hibernate/EclipseLink/OpenJPA? Soll man transaktionsgebunden oder konversationsorientiert arbeiten? Welche Neuerungen sind für JPA 2.1 geplant? Dieser Talk beantwortet die Fragen anhand diverser Beispiele aus der Praxis.

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

  • Be the first to like this

No Downloads
Views
Total views
1,221
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
26
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungen

  1. 1. Java Persistence in ActionEinsatz von JPA 2.x in Java-EE-Anwendungen Dirk Weil | GEDOPLAN
  2. 2. Dirk Weil • GEDOPLAN GmbH, Bielefeld • Java EE seit 1998 • Konzeption und Realisierung • Vorträge • Seminare • Veröffentlichungen2 Java Persistence in Action dirk.weil@gedoplan.de
  3. 3. ZEILEN3 Java Persistence in Action dirk.weil@gedoplan.de
  4. 4. Java Persistence in EE-Anwendungen • Basics: – META-INF/persistence.xml referenziert Datasource <persistence …> <persistence-unit name="beantrial"> <jta-data-source>jdbc/beantrial</jta-data-source> … – EntityManager-Bereitstellung per Injektion @PersistenceContext(unitName = "beantrial") EntityManager entityManager;4 Java Persistence in Action dirk.weil@gedoplan.de
  5. 5. Java Persistence in EE-Anwendungen • The CDI way: public class EntityManagerProducer { @PersistenceContext(unitName = "beantrial") @Produces EntityManager entityManager; public class PersonRepository { @Inject EntityManager entityManager; public class ProjektRepository { @Inject EntityManager entityManager; public class FirmaRepository { @Inject EntityManager entityManager;5 Java Persistence in Action dirk.weil@gedoplan.de
  6. 6. Entity Manager Lifecycle • EM-Lebensdauer Entity-Management-Zeit – Entities werden detached – Nachladen von Lazy-Werten etc. nicht mehr möglich alle evtl. benötigten Werte müssen geladen sein • Remote-Anwendung (Swing, Java FX, …) – Entities im Client sind stets detached • Web-Anwendung (JSF, …) – Render-Phase, Folgerequests?6 Java Persistence in Action dirk.weil@gedoplan.de
  7. 7. Entity Manager Lifecycle <h:dataTable value="#{personModel.personen}" var="person"> … <h:… value="#{person.hobbies}" /> … LazyLoad Exception ? @Entity public class Person { @ElementCollection(fetch = FetchType.LAZY) private List<String> hobbies; @Model public class PersonModel { public List<Person> getPersonen() { … personRepository.findAll() …7 Java Persistence in Action dirk.weil@gedoplan.de
  8. 8. Entity Manager Lifecycle • EM-Optionen: – Transaction-scoped – (Extended)* verschiedene – Application-managed Kombinationen möglich • Patterns – Eager Loading – Open Entity Manager in View – Conversational Entity Manager *nur Stateful EJBs – nicht weiter betrachtet8 Java Persistence in Action dirk.weil@gedoplan.de
  9. 9. Transaction-scoped Entity Manager • Standard für container-managed Entity Manager @Transactional public class PersonRepository { @Inject EntityManager entityManager; public void persist(Person entity) { … } public List<Person> findAll() { … } public class EntityManagerProducer { @PersistenceContext(unitName = "beantrial") @Produces EntityManager entityManager;9 Java Persistence in Action dirk.weil@gedoplan.de
  10. 10. Transaction-scoped Entity Manager • Start: Erste Nutzung des EM in einer TX • Ende: TX-Ende alle Entities werden detached • TX-Steuerung – per CDI Interceptor @Transactional – per EJB – mittels UserTransaction – häufig für (Teil-)Geschäftsprozesse (nur für CRUD wäre ein Antipattern)10 Java Persistence in Action dirk.weil@gedoplan.de
  11. 11. Transaction-scoped Entity Manager <h:dataTable value="#{personModel.personen}" …> View … <h:… value="#{person.hobbies}" /> detached Model @Model public class PersonModel { public List<Person> getPersonen() { … personRepository.findAll() … TX Service @Transactional public class PersonRepository { managed public List<Person> findAll() { … } DB11 Java Persistence in Action dirk.weil@gedoplan.de
  12. 12. Transaction-scoped Entity Manager • Eager Loading nötig – deklarativ @ElementCollection(fetch = FetchType.EAGER) private List<String> hobbies; – oder durch expliziten public void loadLazyAttributes() { Zugriff this.hobbies.size();12 Java Persistence in Action dirk.weil@gedoplan.de
  13. 13. Transaction-scoped Entity Manager • Code Browsing: Personenverwaltung mit detached Entities (Download: www.gedoplan.de Blog13 Java Persistence in Action dirk.weil@gedoplan.de
  14. 14. Transaction-scoped Entity Manager • Alternative: Transaction per Request TX <h:dataTable value="#{personModel.personen}" …> View … <h:… value="#{person.hobbies}" /> Model @Model public class PersonModel { public List<Person> getPersonen() { … personRepository.findAll() … …14 Java Persistence in Action dirk.weil@gedoplan.de
  15. 15. Transaction-scoped Entity Manager • Transaction per Request – mittels Servlet Filter – mittels JSF Phase Listener – Seam Transaction / Seam Faces Achtung: Per Default aktiv ! (Abschalten: Siehe www.gedoplan.de Blog)15 Java Persistence in Action dirk.weil@gedoplan.de
  16. 16. Transaction-scoped Entity Manager • Einfaches Verfahren • Eager Loading – ist aufwändig – hebelt Lazy-Optimierungen aus • TX per Request – durchbricht normale Architektur – nicht für Multi-Request-Fälle geeignet16 Java Persistence in Action dirk.weil@gedoplan.de
  17. 17. Application-managed Entity Manager • Nutzung von EntityManagerFactory • Lifecycle wird von Anwendung bestimmt public class EntityManagerProducer { @PersistenceUnit(unitName = "beantrial") EntityManagerFactory entityManagerFactory; @Produces public EntityManager createEntityManager() { return this.entityManagerFactory.createEntityManager(); } public void closeEntityManager(@Disposes @Any EntityManager em) { if (em.isOpen()) em.close(); }17 Java Persistence in Action dirk.weil@gedoplan.de
  18. 18. Application-managed Entity Manager • persist, merge, remove auch ohne TX erlaubt • Änderungen werden erst durch Commit abgelegt • Entity Manager nicht automatisch TX-gebunden @Transactional public void saveAll() { this.entityManager.joinTransaction(); }18 Java Persistence in Action dirk.weil@gedoplan.de
  19. 19. Request-scoped Entity Manager @Produces • Request @RequestScoped Scope public EntityManager createEntityManager() { = Open Entity Manager in View View <h:dataTable value="#{personModel.personen}" …> Entity Manager … <h:… value="#{person.hobbies}" /> Model @Model public class PersonModel { public List<Person> getPersonen() { … personRepository.findAll() … TX Service @Transactional public class PersonRepository { public void saveAll() { … } DB19 Java Persistence in Action dirk.weil@gedoplan.de
  20. 20. Conversation-scoped Entity Manager • Conversational @Produces @ConversationScoped Entity Manager public EntityManager createEntityManager() { Request 1 EM Request 2 Conversation.begin() Request 3 EM Request 4 Conversation.end()20 Java Persistence in Action dirk.weil@gedoplan.de
  21. 21. Conversation-scoped Entity Manager • ABER: – Conversation Scope ist passivating – Objekte in ihm müssen serialisierbar sein – EntityManager nicht notwendigerweise Serializable • Abhilfe: Serializable-Wrapper21 Java Persistence in Action dirk.weil@gedoplan.de
  22. 22. Conversation-scoped Entity Manager • Serializable-Wrapper: @Produces @ConversationScoped public EntityManager createEntityManager() { EntityManager em = entityManagerFactory.createEntityManager(); if (!(em instanceof Serializable)) { ClassLoader loader = em.getClass().getClassLoader(); Class<?>[] ifs = { EntityManager.class, Serializable.class }; EMInvocationHandler handler = new EMInvocationHandler(em); em = (EntityManager) Proxy.newProxyInstance(loader, if, handler); } return em; }22 Java Persistence in Action dirk.weil@gedoplan.de
  23. 23. Conversation-scoped Entity Manager • Serializable-Wrapper:class EMInvocationHandler implements InvocationHandler, Serializable { private transient EntityManager em; public EntityManagerInvocationHandler(EntityManager em) { this.em = em; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (this.entityManager == null) throw new IllegalStateException("EntityManager is null"); return method.invoke(this.em, args); }}23 Java Persistence in Action dirk.weil@gedoplan.de
  24. 24. Conversation-scoped Entity Manager • Serializable-Wrapper: – Prinzip Hoffnung: Wahrscheinlich keine Passivierung; wenn doch, ordentliche Fehlermeldung. – Ungeeignet für Replikation24 Java Persistence in Action dirk.weil@gedoplan.de
  25. 25. Conversation-scoped Entity Manager • Code Browsing: Personenverwaltung mit attached Entities (Download: www.gedoplan.de Blog25 Java Persistence in Action dirk.weil@gedoplan.de
  26. 26. SQL-Zugriffe im Beispiel Aktion TX-scoped EM Conv-scoped EM Anzeige aller Personen SELECT ID, ... FROM PERSON dito Auswahl einer Person zum Editieren SELECT ID, ... FROM PERSON WHERE (ID = ?) SELECT TEL, ... FROM PERSON_TEL dito WHERE (PERSON_TEL.Person_ID = ?) SELECT HOBBY, ... FROM PERSON_HOBBY WHERE (PERSON_HOBBY.Person_ID = ?)26 Java Persistence in Action dirk.weil@gedoplan.de
  27. 27. SQL-Zugriffe im Beispiel Aktion TX-scoped EM Conv-scoped EM Ändern des Vornamens und Speichern der Person SELECT ID, ... FROM PERSON WHERE (ID = ?) SELECT TEL, ... FROM PERSON_TEL WHERE (PERSON_TEL.Person_ID = ?) SELECT HOBBY, ... FROM PERSON_HOBBY WHERE (PERSON_HOBBY.Person_ID = ?) UPDATE PERSON SET VORNAME = ? dito WHERE (ID = ?)27 Java Persistence in Action dirk.weil@gedoplan.de
  28. 28. TX- oder Conversation-scoped? • Transaction-scoped EM einfaches Vorgehen speichert nur das, was explizit übergeben wird • Conversation-scoped EM vermeidet Lazy-Load-Effekte im Web-Anwendungen erzeugt weniger DB-Zugriffe speichert immer alle Änderungen benötigt mehr Speicher funktioniert nicht im Cluster oder für Remote-Clients28 Java Persistence in Action dirk.weil@gedoplan.de
  29. 29. JPA 2.1 – Whats coming? • Query-Erweiterungen – ON: Join-Filter select p.name, count(b) from Publisher p left join p.books b on b.bookType = BookType.PAPERBACK group by p.name – TREAT: Downcast (inkl. Filterung) select s from StorageLocation s where treat(s.product as Book).bookType = BookType.HARDCOVER – FUNCTION: Aufruf von DB-Funktionen select c from Customer c where function(hasGoodCredit, c.balance, c.creditLimit)29 Java Persistence in Action dirk.weil@gedoplan.de
  30. 30. JPA 2.1 – Whats coming? • Bulk Update/Delete für Criteria Query CriteriaUpdate<Product> criteriaUpdate = criteriaBuilder.createCriteriaUpdate(Product.class); Root<Product> p = criteriaUpdate.from(Product.class); Path<Number> price = p.get(Product_.price); criteriaUpdate.set(price, criteriaBuilder.prod(price, 1.03)); entityManager.createQuery(criteriaUpdate).executeUpdate(); • Stored Procedure Queries StoredProcedureQuery query = entityManager.createStoredProcedureQuery("findMissingProducts");30 Java Persistence in Action dirk.weil@gedoplan.de
  31. 31. JPA 2.1 – Whats coming? • ConstructorResult für native Queries Query query = entityManager.createNativeQuery( "select name, price from product", "NameAndPriceResult"); List<NameAndPrice> result = query.getResultList(); public class NameAndPrice { public NameAndPrice(String name, double price) @Entity @SqlResultSetMapping(name = "NameAndPriceResult", classes = { @ConstructorResult( targetClass = NameAndPrice.class, columns = { @ColumnResult(name = "name"), @ColumnResult(name = "price") }) }) public abstract class Product {31 Java Persistence in Action dirk.weil@gedoplan.de
  32. 32. JPA 2.1 – Whats coming? • Konverter @Converter public class YesNoConverter implements AttributeConverter<Boolean, String> { public String convertToDatabaseColumn(Boolean fieldValue) { if (fieldValue == null) return null; return fieldValue ? "Y" : "N"; } public Boolean convertToEntityAttribute(String columnValue) { if (columnValue == null) return null; return columnValue.equals("Y"); @Entity public abstract class Product { @Convert(converter = YesNoConverter.class) private boolean active;32 Java Persistence in Action dirk.weil@gedoplan.de
  33. 33. JPA 2.1 – Whats coming? • CDI Injection in Entity Listener public class CountryListener { @Inject private AuditService auditService; @PreUpdate public void preUpdate(Object entity) { this.auditService.logUpdate(entity); } @Entity @EntityListeners(CountryListener.class) public class Country {33 Java Persistence in Action dirk.weil@gedoplan.de
  34. 34. JPA 2.1 – Whats coming? • Unsynchronisierter Persistence Context @PersistenceContext( name = "default", synchronization = SynchronizationType.UNSYNCHRONIZED) private EntityManager entityManager; – keine automatische TX-Bindung – API zum Binden an TX: EntityManager.joinTransaction() EntityManager.isJoinedWithTransaction()34 Java Persistence in Action dirk.weil@gedoplan.de
  35. 35. JPA 2.1 – Whats coming? • Dynamische Erzeugung von Named Queries • DDL Handling35 Java Persistence in Action dirk.weil@gedoplan.de
  36. 36. JPA 2.1 – (bisher nur) vorgeschlagen • Fetch groups • Immutable attributes, readonly entities • UUID generator • Multitenancy • Dirty detection • Mapping between JPQL and criteria queries.36 Java Persistence in Action dirk.weil@gedoplan.de
  37. 37. JPA 2.1 – Reicht das? • Ja – für neue Anwendungen – in 90%+ der Fälle • Aber: – Legacy Databases – Performance37 Java Persistence in Action dirk.weil@gedoplan.de
  38. 38. JPA 2.1 – Reicht das? • Legacy Databases EclipseLink Hibernate OpenJPA Optimistic Locking ohne Version weitere Generatoren Inheritance ohne Diskriminator Column Polymorphe Assoziationen Custom CRUD SQL …38 Java Persistence in Action dirk.weil@gedoplan.de
  39. 39. JPA 2.1 – Reicht das? • Performance EclipseLink Hibernate OpenJPA R/O Entities Index Eager Load Tuning Batch Fetching Partitioning Cascading Delete in DB …39 Java Persistence in Action dirk.weil@gedoplan.de
  40. 40. JPA 2.1 – Reicht das? • Wunschliste ist nicht leer – Vieles bereits proprietär vorhanden • Portabilität ist hohes Gut Standard weiter entwickeln!40 Java Persistence in Action dirk.weil@gedoplan.de
  41. 41. Schön, dass Sie da waren!Di, 20:30: Java EE Day PanelMi, 16:30: Gute Zeilen, schlechte ZeilenMi, 19:45: Java on Tracks dirk.weil@gedoplan.de

×