SlideShare uma empresa Scribd logo
1 de 52
Baixar para ler offline
Optimierung von JPA-Anwendungen




Java User Group Berlin Brandenburg, 31.01.2013



Dirk Weil, GEDOPLAN GmbH
Dirk Weil

  GEDOPLAN GmbH, Bielefeld
  Java EE seit 1998
  Konzeption und
  Realisierung
  Vorträge
  Seminare
  Veröffentlichungen
Optimierung von JPA-Anwendungen
           Laufzeit
                                         Memory




                       Providerunabhängig

         EclipseLink                              …
                             Hibernate



                                                      3
Id-Generierung

  Entity-Klassen müssen Id   haben
     PK in der DB
     Feld oder
                             @Entity
     Property                public class SomeEntity
     mit @Id                 {
                               @Id
                               private int id;
                               …


  Empfehlenswert: Technische Id
    Problem: Erzeugung eindeutiger Werte

                                                       4
Id-Generierung

  JPA-Feature: @GeneratedValue
     Nutzt DB-Sequenzen,            @Id
     Identity Columns oder          @GeneratedValue
     Sequenz-Tabellen               private int id;

  Probleme:
     Id erst nach persist gesetzt
        equals?, hashCode?
     Id-Übernahme kostet Zeit




                                                      5
Id-Generierung

  Alternative: BYO-ID (selbst machen)
     Id auch in transitiven Objekten gesetzt
     Insert ohne Zusatzaufwand
     Achtung: i. A. nicht trivial

     Z. B.: UUID


  @Id
  private String id
    = new com.eaio.uuid.UUID().toString();

                                               6
Id-Generierung

  @GeneratedValue signifikant langsamer
  (OOTB)
                                                          Insert 50.000 einfache Entries
                                                                in 1.000er Batches
                                  80.000

                                  70.000

                                  60.000
                  Millisekunden



                                  50.000

                                  40.000

                                  30.000

                                  20.000

                                  10.000

                                      0
                                              Derby           MySQL         Oracle        Derby      MySQL       Oracle
                                            EclipseLink     EclipseLink   EclipseLink   Hibernate   Hibernate   Hibernate
                                   BYO-ID     19.864          11.659        22.478       19.240      9.684       7.126
                                   AUTO       21.034          13.537        23.663       74.804      12.214      70.814


                                                                                                                            7
Id-Generierung

  Tuning: Höhere Allocation Size
   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE,
                   generator = "ArtikelIdGenerator")
   @SequenceGenerator(name = "ArtikelIdGenerator",
                      allocationSize = 1000)
   private@Id id;
           int
          @GeneratedValue(strategy = GenerationType.TABLE,
                          generator = "ArtikelIdGenerator")
          @TableGenerator(name = "ArtikelIdGenerator",
                          allocationSize = 1000)
          private int id;


     Leider nicht verfügbar bei IDENTITY
                                                         8
Id-Generierung
                 Laufzeit vs. Allocation Size
 80.000


 70.000


 60.000


 50.000


 40.000


 30.000


 20.000


 10.000


     0
          1           10                  100   1000



                                                       9
Relationship Loading

  Relationen werden durch Felder mit @OneToOne, …,
  @ManyToMany repräsentiert
                          @Entity
                          public class Publisher
   @Entity                {
   public class Book        @OneToMany(mappedBy="publisher")
   {                        public List<Book> books;
     @ManyToOne
     public Publisher publisher;




                                                          10
Relationship Loading

  Relationen-Parameter: fetch
  Referenzierte Entities direkt laden?
     EAGER: Direkt
     LAZY: Später bei Bedarf




     @ManyToOne(fetch = FetchType.LAZY)
     private Artikel artikel;


                                          11
Relationship Loading

  Bsp.: Auftragsposition bearbeiten
     Ist Owner der n:1-Relation zu Artikel

                     1    *
         Kunde                  Auftrag
            *                        1
            1                        *
                               Auftrags      *   1
         Land                                        Artikel
                               Position

                                @Entity
                                public class AuftragsPosition
                                {
                                  @ManyToOne
                                  private Artikel artikel;

                                                                12
Relationship Loading
                           AuftragsPosition aufPos
                           = em.find(AuftragsPosition.class, id);
    Annahme:               …
    Verwendet nur
    AuftragsPosition

      @ManyToOne                  @ManyToOne(fetch=FetchType.LAZY)
      private Artikel artikel;    private Artikel artikel;




select …                                  select …
from AuftragsPosition                     from AuftragsPosition
left outer join Artikel                   where …
where …


                                                                  13
Relationship Loading
                           AuftragsPosition aufPos
                           = em.find(AuftragsPosition.class, id);
    Annahme:               Artikel artikel = aufPos.getArtikel();
    Verwendet auch         …
    Artikel

      @ManyToOne                  @ManyToOne(fetch=FetchType.LAZY)
      private Artikel artikel;    private Artikel artikel;




select …                     select … from AuftragsPosition where …
from AuftragsPosition
left outer join Artikel      select … from Artikel where …
where …


                                                                14
Relationship Loading

  Bsp.: Kunde bearbeiten
     Ist Owner der 1:n-Relation zu Auftrag

                    1    *
        Kunde                  Auftrag
            *                       1
            1                       *
                              Auftrags       *   1
         Land                                        Artikel
                              Position

      @Entity
      public class Kunde
      {
        @OneToMany(mappedBy="kunde")
        private Set<Auftrag> auftraege;

                                                               15
Relationship Loading
                            Kunde kunde
    Annahme:                  = em.find(Kunde.class, id);…
    Verwendet
    nur Kunde

@ManyToOne(fetch=FetchType.EAGER)   @ManyToOne
private Set<Auftrag> auftraege;     private Set<Auftrag> auftraege;




select …                                    select …
from Kunde                                  from Kunde
left outer join Auftrag                     where …
left outer join AuftragsPosition
where …

                                                                  16
Relationship Loading

  Messergebnis
  (1000 Interationen, Hibernate, MySQL)

                             EAGER         LAZY
    Nur AuftragsPosition    2.967 ms      2.505 ms   - 15 %
    Auch Artikel            2.959 ms      4.305 ms   + 45 %


    Nur Kunde              30.295 ms      4.848 ms   - 84 %


            = Default-Einstellung


                                                              17
Relationship Loading

  Fazit:
     Zugriffsverhalten genau analysieren

     Default ist schon recht gut

     Besser: Immer LAZY verwenden
     und bei Bedarf Fetch Joins nutzen




                                           18
Relationship Loading

  Fetch Joins mit JPQL
     leider nur einstufig erlaubt


  select ap from Auftragsposition ap
            left fetch join ap.artikel
            ...




                                         19
Relationship Loading

  Fetch Joins mit Criteria Query

   CriteriaQuery<Auftrag> cQuery
     = builder.createQuery(Auftrag.class);
   Root<Auftrag> a
     = cQuery.from(Auftrag.class);

   a.fetch(Auftrag_.auftragsPositionen)
    .fetch(AuftragsPosition_.artikel);

   …

                                             20
Basic Attribute Loading

  Fetch-Strategie auch für einfache Werte wählbar
   @Basic(fetch = FetchType.LAZY)
   private String longAdditionalInfo;

  Lazy Loading sinnvoll bei
     selten genutzten Werten
     umfangreichen Daten




                                                    21
Basic Attribute Loading

  Messergebnis
    Lesen von Kunden
    10 'ungenutzte' Strings à 150 chars
    1000 Interationen, EclipseLink, Oracle


         EAGER           LAZY
        7.204 ms        6.820 ms      -5 %


                   = Default-Einstellung


                                             22
Lazy-Load-Verfahren

  Proxy

   @OneToMany
   private Set<Auftrag> auftraege



             get(…)


                         ?
                                    DB


                                         23
Lazy-Load-Verfahren

  Instrumentierung

   @Basic(fetch = FetchType.LAZY)
   private String longAdditionalInfo;



               get(…)
                        ?
                                        DB


                                             24
Bytecode-Instrumentierung
                   Eclipselink
                        Verfahren                       SE EE
 @Basic        Entity Instrumentation
 @xxxToOne Entity Instrumentation
 @xxxToMany Collection Proxy

                             Hibernate
                                 Verfahren                      SE EE
             @Basic     Entity Instrumentation
             @xxxToOne Attribute Proxy
             @xxxToMany Collection Proxy
         =   Standard
         =   Providerspezifische Konfiguration erforderlich
                                                                        25
Caching

  EntityManager   JPA Provider


          1st         2nd
          Level       Level
          Cache       Cache      DB



                      Query
                      Cache


                                      26
First Level Cache                              EntityManager


                                                        1st
                                                        Level
  Standard                                              Cache


  Je EntityManager

  Enthält in Sitzung geladene Objekte
     Achtung: Speicherbedarf!
     ggf. explizit entlasten (clear, detach)




                                                                27
First Level Cache

  Arbeitet          // Kunden mit bestimmter Id laden
  sitzungs-         EntityManager em1 = emf.createEntityManager();
  bezogen           Kunde k1 = em1.find(Kunde.class, id);

                    // Gleichen Kunden in 2. Session verändern
                    EntityManager em2 = emf.createEntityManager();
                    em2.getTransaction().begin();
                    Kunde k2 = em2.find(Kunde.class, id);
                    k2.setName("…");
                    em2.getTransaction().commit();

                    // Gleichen Kunden in 1. Session erneut laden
                    Kunde k3 = em1.find(Kunde.class, id);
                    // ist unverändert!



                                                               28
First Level Cache

  HashMap-Semantik
    benötigt Key
    wird für Queries nicht benutzt

// Kunden mit bestimmter Id laden
EntityManager em = emf.createEntityManager();
Kunde k1 = em.find(Kunde.class, id);

// Query nach gleichem Kunden geht erneut zur DB!
Kunde k2 = em.createQuery("select k from Kunde k " +
                          "where k.id=:id", Kunde.class)
             .setParameter("id", id)
             .getSingleResult();

                                                           29
Query Cache

   Provider-spezifisch
   Speichert Result Set IDs zu Queries


TypedQuery<Kunde> query
= em.createQuery("select k from Kunde k where k.name=:name",
                 Kunde.class);
query.setParameter("name", "OPQ GbR");
… // Query Cache einschalten
Kunde kunde = query.getSingleResult();



["select k from Kunde k where k.name=:name", "OPQ GbR"]   [id1]


                                                              30
Query Cache

      Trotz mehrfacher Query
      nur ein DB-Zugriff


while (…)
{
  TypedQuery<Kunde> query
    = em.createQuery("select k from Kunde k where k.name=:name",
                     Kunde.class);
  query.setParameter("name", "OPQ GbR");
  query.setHint(…) // Query Cache einschalten (providerabh.!)
  Kunde kunde = query.getSingleResult();
  …
}


                                                             31
Query Cache

  EclipseLink

   TypedQuery<Kunde> query = em.createQuery(…);
   query.setHint("eclipselink.cache-usage",
                 "CheckCacheThenDatabase");
   …

  Hibernate:
   TypedQuery<Kunde> query = em.createQuery(…);
   query.setHint("org.hibernate.cacheable", true);
   …


  (Aktivierung in der Konfiguration notwendig)

                                                     32
Second Level Cache

  JPA 2.0 unterstützt 2nd Level Cache
     nur rudimentäre Konfiguration
     Providerspezifische
     Konfiguration
     in der Praxis
     unabdingbar                        EntityManager
                                                         JPA Provider




                                                 1st       2nd
                                                 Level     Level
                                                 Cache     Cache




                                                                        33
Second Level Cache

  Providerspezifische Implementierung
     Cache-Provider
     Infinispan, EHCache, OSCache, …
     Cache-Strategien
     read-only, read-write, …
     Storage
     Memory, Disk, Cluster, …




                                        34
Second Level Cache

  Wirkt applikationsweit
  Semantik ähnlich HashMap
  Ladereihenfolge:
     1st Level Cache (EntityManager)
     2nd Level Cache, falls enabled
     DB




                                       35
Second Level Cache

  Vorteil bei häufig genutzten Daten
     Konstanten
     selten veränderte Daten
     nur von dieser Anwendung veränderte Daten




                                                 36
Second Level Cache

  Bsp.: Stammdaten-Entity Land
                                                   Kunde
     wird n:1 von Kunde
     referenziert                                     *
                                                      1
     nur wenige Land-Werte
                                                   Land
     Länder ändern sich nahezu nie
     Länder können dauerhaft im Cache verbleiben




                                                           37
Second Level Cache
                                                   @Entity
  Konfiguration lt. Spec                           @Cacheable(true)
                                                   public class Land
                                                   {
<persistence-unit name="…">                          …
  <provider>…</provider>
  <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
  …


                           Cache aktiv für …
     ALL                   alle Entities
     NONE                  keine Klasse
     ENABLE_SELECTIVE      nur @Cacheable(true)
     DISABLE_SELECTIVE     alle außer @Cacheable(false)

                                                                  38
Second Level Cache

  EclipseLink
      Default: DISABLE_SELECTIVE

  Hibernate bis Version 3.x
     ignoriert Standard-Konfig
     benötigt eigene Annotation

 @Entity
 @Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
 public class Land
 {
   …


                                                      39
Second Level Cache

  Messergebnis
  (1000 Interationen, EclipseLink, Oracle)

  ohne 2nd Level Cache:            10.883 ms
  mit 2nd Level Cache für Land:     6.549 ms




                                               40
Paginierung

    Queries mit großer Ergebnismenge
    'häppchenweise' verarbeiten

TypedQuery<Artikel> query
= em.createQuery("select a from Artikel a", Artikel.class);
query.setFirstResult(50);
query.setMaxResults(10);
List<Artikel> result = query.getResultList();



                select …
                from Artikel
                where … and rownum>=50 and rownum<60

                                                              41
Paginierung

  Eingeschränkt oder effektlos bei 1:n/m:n-Relationen mit:
      Eager Loading
      Fetch Joins
  Join erzeugt kartesisches Produkt
  Providerabhängige Lösung:
      Ausführung im Memory
      Ausführung mehrerer SQL-Befehle




                                                             42
Inheritance

  Mehrere Abbildungen denkbar:
      Alles in einer Tabelle
      Eine Tabelle pro Klasse
      Eine Tabelle pro konkreter Klasse
  Strategie-Auswahl mit @Inheritance


                                           <abstract>
                                           Vehicle



                                     Car                Ship

                                                               43
Inheritance

  SINGLE_TABLE

   @Entity
   @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
   public abstract class Vehicle
   {
     …




                                                         44
Inheritance

  JOINED
   @Entity
   @Inheritance(strategy=InheritanceType.JOINED)
   public abstract class Vehicle
   {
     …




                                                   45
Inheritance

  TABLE_PER_CLASS
   @Entity
   @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
   public abstract class Vehicle
   {
     …




                                                        46
Inheritance

  Laufzeitvergleich für Queries
     auf Basisklasse
     auf abgeleitete Klasse
                     SINGLE_        TABLE_      JOINED
                      TABLE       PER_CLASS
     Basisklasse     2.705 ms     29.359 ms     3.434 ms
     Subklasse       2.505 ms     1.435 ms      3.377 ms

  (1000 Iterationen, Ergebnis ca. 100 Einträge, Hibernate, MySQL)




                                                                    47
Inheritance

  Optimale Performanz liefern
  SINGLE_TABLE und TABLE_PER_CLASS
  Aber: Auch andere Implikationen
  Genaue Analyse notwendig




                                     48
Providerabhängiges

  Batch Size

  Lazy-Varianten

  Cache-Strategien

  Prepared Statement Cache




                             49
Providerabhängiges

  Load Groups

  Change Detection

  DB Dialects

  …




                     50
Fazit

  Viele Optimierungen providerunabhängig möglich
  Wesentlich:
      Lazy Loading
      Caching
  Genaue Analyse notwendig
  Messen
  Kein Selbstzweck




                                                   51
Schön, dass Sie da waren!




                            dirk.weil@gedoplan.de

Mais conteúdo relacionado

Mais procurados

Keycloak theme customization
Keycloak theme customizationKeycloak theme customization
Keycloak theme customizationRavi Yasas
 
Spring framework IOC and Dependency Injection
Spring framework  IOC and Dependency InjectionSpring framework  IOC and Dependency Injection
Spring framework IOC and Dependency InjectionAnuj Singh Rajput
 
Sed & awk the dynamic duo
Sed & awk   the dynamic duoSed & awk   the dynamic duo
Sed & awk the dynamic duoJoshua Thijssen
 
Basic security &amp; info
Basic security &amp; infoBasic security &amp; info
Basic security &amp; infoTola LENG
 
MySQL Slow Query log Monitoring using Beats & ELK
MySQL Slow Query log Monitoring using Beats & ELKMySQL Slow Query log Monitoring using Beats & ELK
MySQL Slow Query log Monitoring using Beats & ELKYoungHeon (Roy) Kim
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday lifeAndrea Iacono
 
Maximizing performance via tuning and optimization
Maximizing performance via tuning and optimizationMaximizing performance via tuning and optimization
Maximizing performance via tuning and optimizationMariaDB plc
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Hitesh-Java
 
Understanding LINQ in C#
Understanding LINQ in C# Understanding LINQ in C#
Understanding LINQ in C# MD. Shohag Mia
 
Evolution of MongoDB Replicaset and Its Best Practices
Evolution of MongoDB Replicaset and Its Best PracticesEvolution of MongoDB Replicaset and Its Best Practices
Evolution of MongoDB Replicaset and Its Best PracticesMydbops
 
kubernetes : From beginner to Advanced
kubernetes : From beginner to Advancedkubernetes : From beginner to Advanced
kubernetes : From beginner to AdvancedInho Kang
 
Best practices for queue processing in serverless applications - MAD313 - Chi...
Best practices for queue processing in serverless applications - MAD313 - Chi...Best practices for queue processing in serverless applications - MAD313 - Chi...
Best practices for queue processing in serverless applications - MAD313 - Chi...Amazon Web Services
 
PostgreSQL 15 and its Major Features -(Aakash M - Mydbops) - Mydbops Opensour...
PostgreSQL 15 and its Major Features -(Aakash M - Mydbops) - Mydbops Opensour...PostgreSQL 15 and its Major Features -(Aakash M - Mydbops) - Mydbops Opensour...
PostgreSQL 15 and its Major Features -(Aakash M - Mydbops) - Mydbops Opensour...Mydbops
 
A whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizerA whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizerNikita Popov
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring bootAntoine Rey
 
Analyzing Time Series Data with Apache Spark and Cassandra
Analyzing Time Series Data with Apache Spark and CassandraAnalyzing Time Series Data with Apache Spark and Cassandra
Analyzing Time Series Data with Apache Spark and CassandraPatrick McFadin
 
Oracle advanced queuing
Oracle advanced queuingOracle advanced queuing
Oracle advanced queuingGurpreet singh
 

Mais procurados (20)

Keycloak theme customization
Keycloak theme customizationKeycloak theme customization
Keycloak theme customization
 
Spring framework IOC and Dependency Injection
Spring framework  IOC and Dependency InjectionSpring framework  IOC and Dependency Injection
Spring framework IOC and Dependency Injection
 
Sed & awk the dynamic duo
Sed & awk   the dynamic duoSed & awk   the dynamic duo
Sed & awk the dynamic duo
 
Basic security &amp; info
Basic security &amp; infoBasic security &amp; info
Basic security &amp; info
 
MySQL Slow Query log Monitoring using Beats & ELK
MySQL Slow Query log Monitoring using Beats & ELKMySQL Slow Query log Monitoring using Beats & ELK
MySQL Slow Query log Monitoring using Beats & ELK
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday life
 
Maximizing performance via tuning and optimization
Maximizing performance via tuning and optimizationMaximizing performance via tuning and optimization
Maximizing performance via tuning and optimization
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Understanding LINQ in C#
Understanding LINQ in C# Understanding LINQ in C#
Understanding LINQ in C#
 
Evolution of MongoDB Replicaset and Its Best Practices
Evolution of MongoDB Replicaset and Its Best PracticesEvolution of MongoDB Replicaset and Its Best Practices
Evolution of MongoDB Replicaset and Its Best Practices
 
Db2 cheat sheet for development
Db2 cheat sheet for developmentDb2 cheat sheet for development
Db2 cheat sheet for development
 
kubernetes : From beginner to Advanced
kubernetes : From beginner to Advancedkubernetes : From beginner to Advanced
kubernetes : From beginner to Advanced
 
Best practices for queue processing in serverless applications - MAD313 - Chi...
Best practices for queue processing in serverless applications - MAD313 - Chi...Best practices for queue processing in serverless applications - MAD313 - Chi...
Best practices for queue processing in serverless applications - MAD313 - Chi...
 
PostgreSQL 15 and its Major Features -(Aakash M - Mydbops) - Mydbops Opensour...
PostgreSQL 15 and its Major Features -(Aakash M - Mydbops) - Mydbops Opensour...PostgreSQL 15 and its Major Features -(Aakash M - Mydbops) - Mydbops Opensour...
PostgreSQL 15 and its Major Features -(Aakash M - Mydbops) - Mydbops Opensour...
 
A whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizerA whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizer
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring boot
 
Analyzing Time Series Data with Apache Spark and Cassandra
Analyzing Time Series Data with Apache Spark and CassandraAnalyzing Time Series Data with Apache Spark and Cassandra
Analyzing Time Series Data with Apache Spark and Cassandra
 
Oracle advanced queuing
Oracle advanced queuingOracle advanced queuing
Oracle advanced queuing
 
15. DateTime API.ppt
15. DateTime API.ppt15. DateTime API.ppt
15. DateTime API.ppt
 

Destaque

JPA – Der Persistenz-­Standard in der Java EE und SE
JPA – Der Persistenz-­Standard in der Java EE und SEJPA – Der Persistenz-­Standard in der Java EE und SE
JPA – Der Persistenz-­Standard in der Java EE und SEhwilming
 
Effiziente Datenpersistierung mit JPA 2.1 und Hibernate
Effiziente Datenpersistierung mit JPA 2.1 und HibernateEffiziente Datenpersistierung mit JPA 2.1 und Hibernate
Effiziente Datenpersistierung mit JPA 2.1 und HibernateThorben Janssen
 
JPA Optimistic Locking With @Version
JPA Optimistic Locking With @VersionJPA Optimistic Locking With @Version
JPA Optimistic Locking With @VersionGuo Albert
 
Александра Кульчицкая:"Security practices for web applications"
Александра Кульчицкая:"Security practices for web applications"Александра Кульчицкая:"Security practices for web applications"
Александра Кульчицкая:"Security practices for web applications"Anna Shymchenko
 
Лев Сивашов: "Lean Architecture and DCI"
Лев Сивашов: "Lean Architecture and DCI" Лев Сивашов: "Lean Architecture and DCI"
Лев Сивашов: "Lean Architecture and DCI" Anna Shymchenko
 
Александр Третьяков: "Spring Data JPA and MongoDB"
Александр Третьяков: "Spring Data JPA and MongoDB" Александр Третьяков: "Spring Data JPA and MongoDB"
Александр Третьяков: "Spring Data JPA and MongoDB" Anna Shymchenko
 
Вячеслав Блинов: "Spring Integration as an Integration Patterns Provider"
Вячеслав Блинов: "Spring Integration as an Integration Patterns Provider"Вячеслав Блинов: "Spring Integration as an Integration Patterns Provider"
Вячеслав Блинов: "Spring Integration as an Integration Patterns Provider"Anna Shymchenko
 
Константин Маркович: "Creating modular application using Spring Boot "
Константин Маркович: "Creating modular application using Spring Boot "Константин Маркович: "Creating modular application using Spring Boot "
Константин Маркович: "Creating modular application using Spring Boot "Anna Shymchenko
 
Евгений Капинос "Advanced JPA (Java Persistent API)"
Евгений Капинос "Advanced JPA (Java Persistent API)"Евгений Капинос "Advanced JPA (Java Persistent API)"
Евгений Капинос "Advanced JPA (Java Persistent API)"Anna Shymchenko
 
From Microliths To Microsystems
From Microliths To MicrosystemsFrom Microliths To Microsystems
From Microliths To MicrosystemsJonas Bonér
 

Destaque (12)

JPA – Der Persistenz-­Standard in der Java EE und SE
JPA – Der Persistenz-­Standard in der Java EE und SEJPA – Der Persistenz-­Standard in der Java EE und SE
JPA – Der Persistenz-­Standard in der Java EE und SE
 
Effiziente Datenpersistierung mit JPA 2.1 und Hibernate
Effiziente Datenpersistierung mit JPA 2.1 und HibernateEffiziente Datenpersistierung mit JPA 2.1 und Hibernate
Effiziente Datenpersistierung mit JPA 2.1 und Hibernate
 
Batoo jpa
Batoo jpaBatoo jpa
Batoo jpa
 
Kick Start Jpa
Kick Start JpaKick Start Jpa
Kick Start Jpa
 
JPA Optimistic Locking With @Version
JPA Optimistic Locking With @VersionJPA Optimistic Locking With @Version
JPA Optimistic Locking With @Version
 
Александра Кульчицкая:"Security practices for web applications"
Александра Кульчицкая:"Security practices for web applications"Александра Кульчицкая:"Security practices for web applications"
Александра Кульчицкая:"Security practices for web applications"
 
Лев Сивашов: "Lean Architecture and DCI"
Лев Сивашов: "Lean Architecture and DCI" Лев Сивашов: "Lean Architecture and DCI"
Лев Сивашов: "Lean Architecture and DCI"
 
Александр Третьяков: "Spring Data JPA and MongoDB"
Александр Третьяков: "Spring Data JPA and MongoDB" Александр Третьяков: "Spring Data JPA and MongoDB"
Александр Третьяков: "Spring Data JPA and MongoDB"
 
Вячеслав Блинов: "Spring Integration as an Integration Patterns Provider"
Вячеслав Блинов: "Spring Integration as an Integration Patterns Provider"Вячеслав Блинов: "Spring Integration as an Integration Patterns Provider"
Вячеслав Блинов: "Spring Integration as an Integration Patterns Provider"
 
Константин Маркович: "Creating modular application using Spring Boot "
Константин Маркович: "Creating modular application using Spring Boot "Константин Маркович: "Creating modular application using Spring Boot "
Константин Маркович: "Creating modular application using Spring Boot "
 
Евгений Капинос "Advanced JPA (Java Persistent API)"
Евгений Капинос "Advanced JPA (Java Persistent API)"Евгений Капинос "Advanced JPA (Java Persistent API)"
Евгений Капинос "Advanced JPA (Java Persistent API)"
 
From Microliths To Microsystems
From Microliths To MicrosystemsFrom Microliths To Microsystems
From Microliths To Microsystems
 

Semelhante a Optimierung von JPA-­Anwendungen

Java Persistence 2.0
Java Persistence 2.0Java Persistence 2.0
Java Persistence 2.0GFU Cyrus AG
 
Speeding up Java Persistence
Speeding up Java PersistenceSpeeding up Java Persistence
Speeding up Java Persistencegedoplan
 
Optimierung von JPA-Anwendungen
Optimierung von JPA-AnwendungenOptimierung von JPA-Anwendungen
Optimierung von JPA-Anwendungengedoplan
 
Speeding up Java Persistence
Speeding up Java PersistenceSpeeding up Java Persistence
Speeding up Java Persistencegedoplan
 
Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungen
Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-AnwendungenJava Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungen
Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungengedoplan
 
Datenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiDatenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiChristian Baranowski
 
Dependency injection
Dependency injectionDependency injection
Dependency injectionMario Müller
 
Neue Features der Java EE 6
Neue Features der Java EE 6Neue Features der Java EE 6
Neue Features der Java EE 6GFU Cyrus AG
 
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsjavaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsgedoplan
 

Semelhante a Optimierung von JPA-­Anwendungen (11)

Java Persistence 2.0
Java Persistence 2.0Java Persistence 2.0
Java Persistence 2.0
 
Speeding up Java Persistence
Speeding up Java PersistenceSpeeding up Java Persistence
Speeding up Java Persistence
 
Optimierung von JPA-Anwendungen
Optimierung von JPA-AnwendungenOptimierung von JPA-Anwendungen
Optimierung von JPA-Anwendungen
 
Speeding up Java Persistence
Speeding up Java PersistenceSpeeding up Java Persistence
Speeding up Java Persistence
 
Java EE 5
Java EE 5Java EE 5
Java EE 5
 
Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungen
Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-AnwendungenJava Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungen
Java Persistence in Action – Einsatz von JPA 2.x in Java-EE-Anwendungen
 
Datenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiDatenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence Api
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
Neue Features der Java EE 6
Neue Features der Java EE 6Neue Features der Java EE 6
Neue Features der Java EE 6
 
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsjavaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
 
Hibernate Tuning
Hibernate TuningHibernate Tuning
Hibernate Tuning
 

Mais de hwilming

Introduction Machine Learning - Microsoft
Introduction Machine Learning - MicrosoftIntroduction Machine Learning - Microsoft
Introduction Machine Learning - Microsofthwilming
 
A practical introduction to data science and machine learning
A practical introduction to data science and machine learningA practical introduction to data science and machine learning
A practical introduction to data science and machine learninghwilming
 
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014hwilming
 
Creating Mobile Enterprise Applications with Red Hat / JBoss
Creating Mobile Enterprise Applications with Red Hat / JBossCreating Mobile Enterprise Applications with Red Hat / JBoss
Creating Mobile Enterprise Applications with Red Hat / JBosshwilming
 
SAP Integration with Red Hat JBoss Technologies
SAP Integration with Red Hat JBoss TechnologiesSAP Integration with Red Hat JBoss Technologies
SAP Integration with Red Hat JBoss Technologieshwilming
 
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7hwilming
 
JBoss EAP clustering
JBoss EAP clustering JBoss EAP clustering
JBoss EAP clustering hwilming
 
JBoss AS / EAP Clustering
JBoss AS / EAP  ClusteringJBoss AS / EAP  Clustering
JBoss AS / EAP Clusteringhwilming
 
JavaAktuell - Hochverfügbarkeit mit dem JBoss AS 7
JavaAktuell - Hochverfügbarkeit mit dem JBoss AS 7JavaAktuell - Hochverfügbarkeit mit dem JBoss AS 7
JavaAktuell - Hochverfügbarkeit mit dem JBoss AS 7hwilming
 
Integrating SAP the Java EE Way - JBoss One Day talk 2012
Integrating SAP the Java EE Way - JBoss One Day talk 2012Integrating SAP the Java EE Way - JBoss One Day talk 2012
Integrating SAP the Java EE Way - JBoss One Day talk 2012hwilming
 
Aerogear Java User Group Presentation
Aerogear Java User Group PresentationAerogear Java User Group Presentation
Aerogear Java User Group Presentationhwilming
 
The Gear you need to go mobile with Java Enterprise - Jax 2012
The Gear you need to go mobile with Java Enterprise - Jax 2012The Gear you need to go mobile with Java Enterprise - Jax 2012
The Gear you need to go mobile with Java Enterprise - Jax 2012hwilming
 
Need(le) for Speed - Effective Unit Testing for Java EE
Need(le) for Speed - Effective Unit Testing for Java EENeed(le) for Speed - Effective Unit Testing for Java EE
Need(le) for Speed - Effective Unit Testing for Java EEhwilming
 
Need(le) for Speed - Effective Unit Testing for Java EE
Need(le) for Speed - Effective Unit Testing for Java EENeed(le) for Speed - Effective Unit Testing for Java EE
Need(le) for Speed - Effective Unit Testing for Java EEhwilming
 

Mais de hwilming (14)

Introduction Machine Learning - Microsoft
Introduction Machine Learning - MicrosoftIntroduction Machine Learning - Microsoft
Introduction Machine Learning - Microsoft
 
A practical introduction to data science and machine learning
A practical introduction to data science and machine learningA practical introduction to data science and machine learning
A practical introduction to data science and machine learning
 
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
 
Creating Mobile Enterprise Applications with Red Hat / JBoss
Creating Mobile Enterprise Applications with Red Hat / JBossCreating Mobile Enterprise Applications with Red Hat / JBoss
Creating Mobile Enterprise Applications with Red Hat / JBoss
 
SAP Integration with Red Hat JBoss Technologies
SAP Integration with Red Hat JBoss TechnologiesSAP Integration with Red Hat JBoss Technologies
SAP Integration with Red Hat JBoss Technologies
 
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
JavaAktuell - Skalierbare Cluster-Topologien mit dem JBoss AS 7
 
JBoss EAP clustering
JBoss EAP clustering JBoss EAP clustering
JBoss EAP clustering
 
JBoss AS / EAP Clustering
JBoss AS / EAP  ClusteringJBoss AS / EAP  Clustering
JBoss AS / EAP Clustering
 
JavaAktuell - Hochverfügbarkeit mit dem JBoss AS 7
JavaAktuell - Hochverfügbarkeit mit dem JBoss AS 7JavaAktuell - Hochverfügbarkeit mit dem JBoss AS 7
JavaAktuell - Hochverfügbarkeit mit dem JBoss AS 7
 
Integrating SAP the Java EE Way - JBoss One Day talk 2012
Integrating SAP the Java EE Way - JBoss One Day talk 2012Integrating SAP the Java EE Way - JBoss One Day talk 2012
Integrating SAP the Java EE Way - JBoss One Day talk 2012
 
Aerogear Java User Group Presentation
Aerogear Java User Group PresentationAerogear Java User Group Presentation
Aerogear Java User Group Presentation
 
The Gear you need to go mobile with Java Enterprise - Jax 2012
The Gear you need to go mobile with Java Enterprise - Jax 2012The Gear you need to go mobile with Java Enterprise - Jax 2012
The Gear you need to go mobile with Java Enterprise - Jax 2012
 
Need(le) for Speed - Effective Unit Testing for Java EE
Need(le) for Speed - Effective Unit Testing for Java EENeed(le) for Speed - Effective Unit Testing for Java EE
Need(le) for Speed - Effective Unit Testing for Java EE
 
Need(le) for Speed - Effective Unit Testing for Java EE
Need(le) for Speed - Effective Unit Testing for Java EENeed(le) for Speed - Effective Unit Testing for Java EE
Need(le) for Speed - Effective Unit Testing for Java EE
 

Optimierung von JPA-­Anwendungen

  • 1. Optimierung von JPA-Anwendungen Java User Group Berlin Brandenburg, 31.01.2013 Dirk Weil, GEDOPLAN GmbH
  • 2. Dirk Weil GEDOPLAN GmbH, Bielefeld Java EE seit 1998 Konzeption und Realisierung Vorträge Seminare Veröffentlichungen
  • 3. Optimierung von JPA-Anwendungen Laufzeit Memory Providerunabhängig EclipseLink … Hibernate 3
  • 4. Id-Generierung Entity-Klassen müssen Id haben PK in der DB Feld oder @Entity Property public class SomeEntity mit @Id { @Id private int id; … Empfehlenswert: Technische Id Problem: Erzeugung eindeutiger Werte 4
  • 5. Id-Generierung JPA-Feature: @GeneratedValue Nutzt DB-Sequenzen, @Id Identity Columns oder @GeneratedValue Sequenz-Tabellen private int id; Probleme: Id erst nach persist gesetzt equals?, hashCode? Id-Übernahme kostet Zeit 5
  • 6. Id-Generierung Alternative: BYO-ID (selbst machen) Id auch in transitiven Objekten gesetzt Insert ohne Zusatzaufwand Achtung: i. A. nicht trivial Z. B.: UUID @Id private String id = new com.eaio.uuid.UUID().toString(); 6
  • 7. Id-Generierung @GeneratedValue signifikant langsamer (OOTB) Insert 50.000 einfache Entries in 1.000er Batches 80.000 70.000 60.000 Millisekunden 50.000 40.000 30.000 20.000 10.000 0 Derby MySQL Oracle Derby MySQL Oracle EclipseLink EclipseLink EclipseLink Hibernate Hibernate Hibernate BYO-ID 19.864 11.659 22.478 19.240 9.684 7.126 AUTO 21.034 13.537 23.663 74.804 12.214 70.814 7
  • 8. Id-Generierung Tuning: Höhere Allocation Size @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ArtikelIdGenerator") @SequenceGenerator(name = "ArtikelIdGenerator", allocationSize = 1000) private@Id id; int @GeneratedValue(strategy = GenerationType.TABLE, generator = "ArtikelIdGenerator") @TableGenerator(name = "ArtikelIdGenerator", allocationSize = 1000) private int id; Leider nicht verfügbar bei IDENTITY 8
  • 9. Id-Generierung Laufzeit vs. Allocation Size 80.000 70.000 60.000 50.000 40.000 30.000 20.000 10.000 0 1 10 100 1000 9
  • 10. Relationship Loading Relationen werden durch Felder mit @OneToOne, …, @ManyToMany repräsentiert @Entity public class Publisher @Entity { public class Book @OneToMany(mappedBy="publisher") { public List<Book> books; @ManyToOne public Publisher publisher; 10
  • 11. Relationship Loading Relationen-Parameter: fetch Referenzierte Entities direkt laden? EAGER: Direkt LAZY: Später bei Bedarf @ManyToOne(fetch = FetchType.LAZY) private Artikel artikel; 11
  • 12. Relationship Loading Bsp.: Auftragsposition bearbeiten Ist Owner der n:1-Relation zu Artikel 1 * Kunde Auftrag * 1 1 * Auftrags * 1 Land Artikel Position @Entity public class AuftragsPosition { @ManyToOne private Artikel artikel; 12
  • 13. Relationship Loading AuftragsPosition aufPos = em.find(AuftragsPosition.class, id); Annahme: … Verwendet nur AuftragsPosition @ManyToOne @ManyToOne(fetch=FetchType.LAZY) private Artikel artikel; private Artikel artikel; select … select … from AuftragsPosition from AuftragsPosition left outer join Artikel where … where … 13
  • 14. Relationship Loading AuftragsPosition aufPos = em.find(AuftragsPosition.class, id); Annahme: Artikel artikel = aufPos.getArtikel(); Verwendet auch … Artikel @ManyToOne @ManyToOne(fetch=FetchType.LAZY) private Artikel artikel; private Artikel artikel; select … select … from AuftragsPosition where … from AuftragsPosition left outer join Artikel select … from Artikel where … where … 14
  • 15. Relationship Loading Bsp.: Kunde bearbeiten Ist Owner der 1:n-Relation zu Auftrag 1 * Kunde Auftrag * 1 1 * Auftrags * 1 Land Artikel Position @Entity public class Kunde { @OneToMany(mappedBy="kunde") private Set<Auftrag> auftraege; 15
  • 16. Relationship Loading Kunde kunde Annahme: = em.find(Kunde.class, id);… Verwendet nur Kunde @ManyToOne(fetch=FetchType.EAGER) @ManyToOne private Set<Auftrag> auftraege; private Set<Auftrag> auftraege; select … select … from Kunde from Kunde left outer join Auftrag where … left outer join AuftragsPosition where … 16
  • 17. Relationship Loading Messergebnis (1000 Interationen, Hibernate, MySQL) EAGER LAZY Nur AuftragsPosition 2.967 ms 2.505 ms - 15 % Auch Artikel 2.959 ms 4.305 ms + 45 % Nur Kunde 30.295 ms 4.848 ms - 84 % = Default-Einstellung 17
  • 18. Relationship Loading Fazit: Zugriffsverhalten genau analysieren Default ist schon recht gut Besser: Immer LAZY verwenden und bei Bedarf Fetch Joins nutzen 18
  • 19. Relationship Loading Fetch Joins mit JPQL leider nur einstufig erlaubt select ap from Auftragsposition ap left fetch join ap.artikel ... 19
  • 20. Relationship Loading Fetch Joins mit Criteria Query CriteriaQuery<Auftrag> cQuery = builder.createQuery(Auftrag.class); Root<Auftrag> a = cQuery.from(Auftrag.class); a.fetch(Auftrag_.auftragsPositionen) .fetch(AuftragsPosition_.artikel); … 20
  • 21. Basic Attribute Loading Fetch-Strategie auch für einfache Werte wählbar @Basic(fetch = FetchType.LAZY) private String longAdditionalInfo; Lazy Loading sinnvoll bei selten genutzten Werten umfangreichen Daten 21
  • 22. Basic Attribute Loading Messergebnis Lesen von Kunden 10 'ungenutzte' Strings à 150 chars 1000 Interationen, EclipseLink, Oracle EAGER LAZY 7.204 ms 6.820 ms -5 % = Default-Einstellung 22
  • 23. Lazy-Load-Verfahren Proxy @OneToMany private Set<Auftrag> auftraege get(…) ? DB 23
  • 24. Lazy-Load-Verfahren Instrumentierung @Basic(fetch = FetchType.LAZY) private String longAdditionalInfo; get(…) ? DB 24
  • 25. Bytecode-Instrumentierung Eclipselink Verfahren SE EE @Basic Entity Instrumentation @xxxToOne Entity Instrumentation @xxxToMany Collection Proxy Hibernate Verfahren SE EE @Basic Entity Instrumentation @xxxToOne Attribute Proxy @xxxToMany Collection Proxy = Standard = Providerspezifische Konfiguration erforderlich 25
  • 26. Caching EntityManager JPA Provider 1st 2nd Level Level Cache Cache DB Query Cache 26
  • 27. First Level Cache EntityManager 1st Level Standard Cache Je EntityManager Enthält in Sitzung geladene Objekte Achtung: Speicherbedarf! ggf. explizit entlasten (clear, detach) 27
  • 28. First Level Cache Arbeitet // Kunden mit bestimmter Id laden sitzungs- EntityManager em1 = emf.createEntityManager(); bezogen Kunde k1 = em1.find(Kunde.class, id); // Gleichen Kunden in 2. Session verändern EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin(); Kunde k2 = em2.find(Kunde.class, id); k2.setName("…"); em2.getTransaction().commit(); // Gleichen Kunden in 1. Session erneut laden Kunde k3 = em1.find(Kunde.class, id); // ist unverändert! 28
  • 29. First Level Cache HashMap-Semantik benötigt Key wird für Queries nicht benutzt // Kunden mit bestimmter Id laden EntityManager em = emf.createEntityManager(); Kunde k1 = em.find(Kunde.class, id); // Query nach gleichem Kunden geht erneut zur DB! Kunde k2 = em.createQuery("select k from Kunde k " + "where k.id=:id", Kunde.class) .setParameter("id", id) .getSingleResult(); 29
  • 30. Query Cache Provider-spezifisch Speichert Result Set IDs zu Queries TypedQuery<Kunde> query = em.createQuery("select k from Kunde k where k.name=:name", Kunde.class); query.setParameter("name", "OPQ GbR"); … // Query Cache einschalten Kunde kunde = query.getSingleResult(); ["select k from Kunde k where k.name=:name", "OPQ GbR"] [id1] 30
  • 31. Query Cache Trotz mehrfacher Query nur ein DB-Zugriff while (…) { TypedQuery<Kunde> query = em.createQuery("select k from Kunde k where k.name=:name", Kunde.class); query.setParameter("name", "OPQ GbR"); query.setHint(…) // Query Cache einschalten (providerabh.!) Kunde kunde = query.getSingleResult(); … } 31
  • 32. Query Cache EclipseLink TypedQuery<Kunde> query = em.createQuery(…); query.setHint("eclipselink.cache-usage", "CheckCacheThenDatabase"); … Hibernate: TypedQuery<Kunde> query = em.createQuery(…); query.setHint("org.hibernate.cacheable", true); … (Aktivierung in der Konfiguration notwendig) 32
  • 33. Second Level Cache JPA 2.0 unterstützt 2nd Level Cache nur rudimentäre Konfiguration Providerspezifische Konfiguration in der Praxis unabdingbar EntityManager JPA Provider 1st 2nd Level Level Cache Cache 33
  • 34. Second Level Cache Providerspezifische Implementierung Cache-Provider Infinispan, EHCache, OSCache, … Cache-Strategien read-only, read-write, … Storage Memory, Disk, Cluster, … 34
  • 35. Second Level Cache Wirkt applikationsweit Semantik ähnlich HashMap Ladereihenfolge: 1st Level Cache (EntityManager) 2nd Level Cache, falls enabled DB 35
  • 36. Second Level Cache Vorteil bei häufig genutzten Daten Konstanten selten veränderte Daten nur von dieser Anwendung veränderte Daten 36
  • 37. Second Level Cache Bsp.: Stammdaten-Entity Land Kunde wird n:1 von Kunde referenziert * 1 nur wenige Land-Werte Land Länder ändern sich nahezu nie Länder können dauerhaft im Cache verbleiben 37
  • 38. Second Level Cache @Entity Konfiguration lt. Spec @Cacheable(true) public class Land { <persistence-unit name="…"> … <provider>…</provider> <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> … Cache aktiv für … ALL alle Entities NONE keine Klasse ENABLE_SELECTIVE nur @Cacheable(true) DISABLE_SELECTIVE alle außer @Cacheable(false) 38
  • 39. Second Level Cache EclipseLink Default: DISABLE_SELECTIVE Hibernate bis Version 3.x ignoriert Standard-Konfig benötigt eigene Annotation @Entity @Cache(usage = CacheConcurrencyStrategy.READ_ONLY) public class Land { … 39
  • 40. Second Level Cache Messergebnis (1000 Interationen, EclipseLink, Oracle) ohne 2nd Level Cache: 10.883 ms mit 2nd Level Cache für Land: 6.549 ms 40
  • 41. Paginierung Queries mit großer Ergebnismenge 'häppchenweise' verarbeiten TypedQuery<Artikel> query = em.createQuery("select a from Artikel a", Artikel.class); query.setFirstResult(50); query.setMaxResults(10); List<Artikel> result = query.getResultList(); select … from Artikel where … and rownum>=50 and rownum<60 41
  • 42. Paginierung Eingeschränkt oder effektlos bei 1:n/m:n-Relationen mit: Eager Loading Fetch Joins Join erzeugt kartesisches Produkt Providerabhängige Lösung: Ausführung im Memory Ausführung mehrerer SQL-Befehle 42
  • 43. Inheritance Mehrere Abbildungen denkbar: Alles in einer Tabelle Eine Tabelle pro Klasse Eine Tabelle pro konkreter Klasse Strategie-Auswahl mit @Inheritance <abstract> Vehicle Car Ship 43
  • 44. Inheritance SINGLE_TABLE @Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) public abstract class Vehicle { … 44
  • 45. Inheritance JOINED @Entity @Inheritance(strategy=InheritanceType.JOINED) public abstract class Vehicle { … 45
  • 46. Inheritance TABLE_PER_CLASS @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public abstract class Vehicle { … 46
  • 47. Inheritance Laufzeitvergleich für Queries auf Basisklasse auf abgeleitete Klasse SINGLE_ TABLE_ JOINED TABLE PER_CLASS Basisklasse 2.705 ms 29.359 ms 3.434 ms Subklasse 2.505 ms 1.435 ms 3.377 ms (1000 Iterationen, Ergebnis ca. 100 Einträge, Hibernate, MySQL) 47
  • 48. Inheritance Optimale Performanz liefern SINGLE_TABLE und TABLE_PER_CLASS Aber: Auch andere Implikationen Genaue Analyse notwendig 48
  • 49. Providerabhängiges Batch Size Lazy-Varianten Cache-Strategien Prepared Statement Cache 49
  • 50. Providerabhängiges Load Groups Change Detection DB Dialects … 50
  • 51. Fazit Viele Optimierungen providerunabhängig möglich Wesentlich: Lazy Loading Caching Genaue Analyse notwendig Messen Kein Selbstzweck 51
  • 52. Schön, dass Sie da waren! dirk.weil@gedoplan.de