SlideShare ist ein Scribd-Unternehmen logo
1 von 41
Downloaden Sie, um offline zu lesen
Java Persistence in Action
Einsatz 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
    • Seminare
    • Veröffentlichungen



2               Java Persistence in Action   dirk.weil@gedoplan.de
ZEILEN

3   Java Persistence in Action   dirk.weil@gedoplan.de
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
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
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
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
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 betrachtet

8                   Java Persistence in Action                          dirk.weil@gedoplan.de
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
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
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() { … }



                                             DB
11                    Java Persistence in Action                 dirk.weil@gedoplan.de
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
Transaction-scoped Entity Manager
     • Code Browsing:
       Personenverwaltung mit detached Entities




                                          (Download: www.gedoplan.de      Blog

13                 Java Persistence in Action                    dirk.weil@gedoplan.de
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
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
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 geeignet


16                    Java Persistence in Action   dirk.weil@gedoplan.de
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
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
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() { … }



                                             DB


19                           Java Persistence in Action                                           dirk.weil@gedoplan.de
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
Conversation-scoped Entity Manager
     • ABER:
       – Conversation Scope ist passivating
       – Objekte in ihm müssen serialisierbar sein
       – EntityManager nicht notwendigerweise
         Serializable


     • Abhilfe: Serializable-Wrapper




21                   Java Persistence in Action      dirk.weil@gedoplan.de
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
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
Conversation-scoped Entity Manager
     • Serializable-Wrapper:
       – Prinzip Hoffnung:
         Wahrscheinlich keine Passivierung;
         wenn doch, ordentliche Fehlermeldung.

       – Ungeeignet für Replikation




24                   Java Persistence in Action   dirk.weil@gedoplan.de
Conversation-scoped Entity Manager
     • Code Browsing:
       Personenverwaltung mit attached Entities




                                           (Download: www.gedoplan.de      Blog

25                  Java Persistence in Action                    dirk.weil@gedoplan.de
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
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
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-Clients

28                     Java Persistence in Action           dirk.weil@gedoplan.de
JPA 2.1 – What's 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
JPA 2.1 – What's 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
JPA 2.1 – What's 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
JPA 2.1 – What's 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
JPA 2.1 – What's 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
JPA 2.1 – What's 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
JPA 2.1 – What's coming?
     • Dynamische Erzeugung von Named Queries
     • DDL Handling




35                Java Persistence in Action   dirk.weil@gedoplan.de
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
JPA 2.1 – Reicht das?
     • Ja
       – für neue Anwendungen
       – in 90%+ der Fälle


     • Aber:
       – Legacy Databases
       – Performance




37                 Java Persistence in Action   dirk.weil@gedoplan.de
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
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
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
Schön, dass Sie da waren!

Di, 20:30: Java EE Day Panel

Mi, 16:30: Gute Zeilen, schlechte Zeilen
Mi, 19:45: Java on Tracks
                                           dirk.weil@gedoplan.de

Weitere ähnliche Inhalte

Andere mochten auch

Sonas Housing Annual Review 2011
Sonas Housing Annual Review 2011Sonas Housing Annual Review 2011
Sonas Housing Annual Review 2011
Sonas_Housing
 
Photo talk
Photo talkPhoto talk
Photo talk
JAMAATON
 
Jpa queries
Jpa queriesJpa queries
Jpa queries
gedoplan
 

Andere mochten auch (17)

What's new in Java EE 7
What's new in Java EE 7What's new in Java EE 7
What's new in Java EE 7
 
CDI
CDICDI
CDI
 
Sonas Housing Annual Review 2011
Sonas Housing Annual Review 2011Sonas Housing Annual Review 2011
Sonas Housing Annual Review 2011
 
Photo talk
Photo talkPhoto talk
Photo talk
 
Feige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-UmfeldFeige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-Umfeld
 
Java Persistence 2.0
Java Persistence 2.0Java Persistence 2.0
Java Persistence 2.0
 
Java in the Cloud - am Beispiel der Google App Engineg
Java in the Cloud - am Beispiel der Google App EnginegJava in the Cloud - am Beispiel der Google App Engineg
Java in the Cloud - am Beispiel der Google App Engineg
 
Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!
 
Neuerungen in JavaServer Faces 2.0
Neuerungen in JavaServer Faces 2.0Neuerungen in JavaServer Faces 2.0
Neuerungen in JavaServer Faces 2.0
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Leichtgewichtige Microservices mit Java EE 7
Leichtgewichtige Microservices mit Java EE 7Leichtgewichtige Microservices mit Java EE 7
Leichtgewichtige Microservices mit Java EE 7
 
Jpa queries
Jpa queriesJpa queries
Jpa queries
 
Infinispan - NoSQL für den Enterprise Java Alltag
Infinispan - NoSQL für den Enterprise Java AlltagInfinispan - NoSQL für den Enterprise Java Alltag
Infinispan - NoSQL für den Enterprise Java Alltag
 
Kernel Masters inauguration slideshare
Kernel Masters inauguration slideshareKernel Masters inauguration slideshare
Kernel Masters inauguration slideshare
 
Java Batch – Der Standard für's Stapeln
Java Batch – Der Standard für's StapelnJava Batch – Der Standard für's Stapeln
Java Batch – Der Standard für's Stapeln
 
KM Placement Assistance Program
KM Placement Assistance ProgramKM Placement Assistance Program
KM Placement Assistance Program
 
Java EE 7 - Enterprise-Anwendungen ohne Ballast
Java EE 7 - Enterprise-Anwendungen ohne BallastJava EE 7 - Enterprise-Anwendungen ohne Ballast
Java EE 7 - Enterprise-Anwendungen ohne Ballast
 

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

Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPA
mh0708
 
Doctrine 2 - An Introduction (German)
Doctrine 2 - An Introduction (German)Doctrine 2 - An Introduction (German)
Doctrine 2 - An Introduction (German)
Michael Romer
 
JPA the Versant Way
JPA the Versant WayJPA the Versant Way
JPA the Versant Way
jubecker
 
2009 03 17 Spring101
2009 03 17 Spring1012009 03 17 Spring101
2009 03 17 Spring101
gueste4be40
 

Ähnlich wie Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungen (20)

Speeding up Java Persistence
Speeding up Java PersistenceSpeeding up Java Persistence
Speeding up Java Persistence
 
Workshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GAWorkshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GA
 
Let's talk about Java EE
Let's talk about Java EELet's talk about Java EE
Let's talk about Java EE
 
Optimierung von JPA-Anwendungen
Optimierung von JPA-AnwendungenOptimierung von JPA-Anwendungen
Optimierung von JPA-Anwendungen
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPA
 
Java Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s StapelnJava Batch: Der neue Standard für‘s Stapeln
Java Batch: Der neue Standard für‘s Stapeln
 
Feature Flags mit Togglz
Feature Flags mit TogglzFeature Flags mit Togglz
Feature Flags mit Togglz
 
Doctrine 2 - An Introduction (German)
Doctrine 2 - An Introduction (German)Doctrine 2 - An Introduction (German)
Doctrine 2 - An Introduction (German)
 
MicroProfile-Anwendungen mit Quarkus
MicroProfile-Anwendungen mit QuarkusMicroProfile-Anwendungen mit Quarkus
MicroProfile-Anwendungen mit Quarkus
 
Java EE 5
Java EE 5Java EE 5
Java EE 5
 
JPA the Versant Way
JPA the Versant WayJPA the Versant Way
JPA the Versant Way
 
Neue Features der Java EE 6
Neue Features der Java EE 6Neue Features der Java EE 6
Neue Features der Java EE 6
 
MicroProfile 2.x: Der alternative Standard
MicroProfile 2.x: Der alternative StandardMicroProfile 2.x: Der alternative Standard
MicroProfile 2.x: Der alternative Standard
 
Backbase Intro
Backbase IntroBackbase Intro
Backbase Intro
 
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
 
Schnell, schneller, Quarkus!!
Schnell, schneller, Quarkus!!Schnell, schneller, Quarkus!!
Schnell, schneller, Quarkus!!
 
WPF Dos n Don'ts - der WPF Rundumschlag
WPF Dos n Don'ts - der WPF RundumschlagWPF Dos n Don'ts - der WPF Rundumschlag
WPF Dos n Don'ts - der WPF Rundumschlag
 
Optimierung von JPA-­Anwendungen
Optimierung von JPA-­AnwendungenOptimierung von JPA-­Anwendungen
Optimierung von JPA-­Anwendungen
 
MVVM mit WPF
MVVM mit WPFMVVM mit WPF
MVVM mit WPF
 
2009 03 17 Spring101
2009 03 17 Spring1012009 03 17 Spring101
2009 03 17 Spring101
 

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

  • 1. Java Persistence in Action Einsatz von JPA 2.x in Java-EE-Anwendungen Dirk Weil | GEDOPLAN
  • 2. Dirk Weil • GEDOPLAN GmbH, Bielefeld • Java EE seit 1998 • Konzeption und Realisierung • Vorträge • Seminare • Veröffentlichungen 2 Java Persistence in Action dirk.weil@gedoplan.de
  • 3. ZEILEN 3 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. 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. 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. 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. 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 betrachtet 8 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. 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. 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() { … } DB 11 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. Transaction-scoped Entity Manager • Code Browsing: Personenverwaltung mit detached Entities (Download: www.gedoplan.de Blog 13 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. 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. 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 geeignet 16 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. 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. 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() { … } DB 19 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. Conversation-scoped Entity Manager • ABER: – Conversation Scope ist passivating – Objekte in ihm müssen serialisierbar sein – EntityManager nicht notwendigerweise Serializable • Abhilfe: Serializable-Wrapper 21 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. 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. Conversation-scoped Entity Manager • Serializable-Wrapper: – Prinzip Hoffnung: Wahrscheinlich keine Passivierung; wenn doch, ordentliche Fehlermeldung. – Ungeeignet für Replikation 24 Java Persistence in Action dirk.weil@gedoplan.de
  • 25. Conversation-scoped Entity Manager • Code Browsing: Personenverwaltung mit attached Entities (Download: www.gedoplan.de Blog 25 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. 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. 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-Clients 28 Java Persistence in Action dirk.weil@gedoplan.de
  • 29. JPA 2.1 – What's 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. JPA 2.1 – What's 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. JPA 2.1 – What's 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. JPA 2.1 – What's 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. JPA 2.1 – What's 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. JPA 2.1 – What's 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. JPA 2.1 – What's coming? • Dynamische Erzeugung von Named Queries • DDL Handling 35 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. JPA 2.1 – Reicht das? • Ja – für neue Anwendungen – in 90%+ der Fälle • Aber: – Legacy Databases – Performance 37 Java Persistence in Action dirk.weil@gedoplan.de
  • 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. 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. 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. Schön, dass Sie da waren! Di, 20:30: Java EE Day Panel Mi, 16:30: Gute Zeilen, schlechte Zeilen Mi, 19:45: Java on Tracks dirk.weil@gedoplan.de