Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Performance Tuning
with
JPA 2.1 and Hibernate
Thorben Janssen
Thorben Janssen (@thjanssen123), 23rd
October 2015
Thorben Janssen
• Independent author and trainer
• Senior developer and architect @ Qualitype GmbH
• CDI 2.0 expert group ...
Performance
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Performance
• Recognize performance problems as early as possible
• Typical causes for performance problems
• Solving perf...
Hibernate Statistics
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Hibernate Statistics
• Activate via system property
• hibernate.generate_statistics = true
• Configure logging
• org.hiber...
Hibernate Statistics
• 08:24:10,916 DEBUG [org.hibernate.stat.internal.ConcurrentStatisticsImpl]
(default task-1) HHH00011...
Hibernate Statistics
08:08:04,960 INFO [org.hibernate.engine.internal.StatisticalLoggingSessionEventListener] (default
tas...
Typical causes for
performance problems
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Typical Causes
• Slow SELECT statements
• Wrong FetchType
• Load same data multiple times
Thorben Janssen (@thjanssen123) ...
Slow SELECT-statements
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Slow SELECTs
• In general no „real“ JPA or Hibernate problem
• Check generated SQL
• Check execution plan of the statement...
Native Query
• Reasons to use native queries:
• JPQL supports only a subset of SQL
• Database specific features
• Native q...
SqlResultSetMapping
• Declarative mapping of query results
@SqlResultSetMapping(
name = "myResultMapping ",
entities = {@E...
SqlResultSetMapping
@SqlResultSetMapping(
name = "myResultMapping",
entities = {@EntityResult(
entityClass = Author.class,...
SqlResultSetMapping
@SqlResultSetMapping(
name = "myResultMapping",
entities = {@EntityResult(...), …},
classes= {@Constru...
SqlResultSetMapping
@SqlResultSetMapping(
name = "myResultMapping",
entities = {@EntityResult(...), …},
classes= {@Constru...
FetchType
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
FetchType
• Defines when the relationship will be fetched
• Static definition in entity mapping
@ManyToMany(mappedBy="auth...
FetchType
• Lazy
• Relationship gets loaded at first access
• Default for to-many relationships
• Eager
• Loads relationsh...
Recommendations
• To-many relationships
• Stick to the default mapping (FetchType.LAZY)
• Use eager fetching for specific ...
Query Specific Fetching
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Query Specific Fetching
• Fetch all required entities with one query
• Fetch Joins
• @NamedEntityGraph
• EntityGraph
Thorb...
Query Specific Fetching
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Fetch Join
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Fetch Join
• Use JOIN FETCH instead of JOIN in JPQL query
List<Author> authors = this.em.createQuery(
"SELECT DISTINCT a F...
Fetch Join
• Advantages
• Relationships gets loaded in same query
• Disadvantages
• Requires a special query for each use ...
@NamedEntityGraph
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
@NamedEntityGraph
• Introduced in JPA 2.1
• Declaratively defines a graph of entities which will be loaded
• Graph is quer...
@NamedEntityGraph
• Define a @NamedEntityGraph
@NamedEntityGraph(
name = "graph.AuthorBooksReviews",
attributeNodes =
@Nam...
@NamedEntityGraph
• Define a @NamedEntityGraph
@NamedEntityGraph(
name = "graph.AuthorBooksReviews",
attributeNodes =
@Nam...
@NamedEntityGraph
• Provide entity graph es hint
EntityGraph graph = this.em.getEntityGraph("graph.AuthorBooks");
this.em....
@NamedEntityGraph
• Fetch graph
• Eager loading for all elements of the graph
• Lazy loading for all other attributes
• Lo...
@NamedEntityGraph
• Advantages
• Relationships gets loaded in same query
• Definition of the graph is independent of the q...
EntityGraph
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
EntityGraph
• Introduced in JPA 2.1
• Dynamic version of @NamedEntityGraph
• Definition via Java API
• Graph is query inde...
EntityGraph
• Define and use EntityGraph
EntityGraph graph = this.em.createEntityGraph(Author.class);
Subgraph<Book> bookS...
EntityGraph
• Advantages
• Relationships gets loaded in same query
• Definition of the graph is independent of the query
•...
Caching
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Caching
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
1st
Level
Cache
Hibernate
Session
1st
Level
Cache
Hibern...
1st Level Cache
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
1st Level Cache
• Activated by default
• Linked to the Hibernate session
• Stores all entities that were used within a ses...
2nd Level Cache
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
2nd Level Cache
• Session independent entity store
• Needs to be activated
• persistence.xml or EntityManagerFactory
• Tra...
2nd Level Cache
• Shared Cache Mode
• ALL cache all entities
• NONE cache no entities
• ENABLE_SELECTIVE cache needs to be...
2nd Level Cache
• Cache configuration
• Cache Retrieve Mode
• How to read entities from the cache
• Cache Store Mode
• How...
Query Cache
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Query Cache
• Stores query results for a query and its parameters
• [„FROM Author WHERE id=?“, 1]  [1]
• Stores only enti...
Query Cache
• Hibernate specific
• Stores query result session independent
• Needs to be activated
• persistence.xml: hibe...
Recommendations
• Only cache data that is seldom updated
• Always benchmark the application when adding or changing cachin...
Resources
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Resources
• JSR 338: JavaTM Persistence API, Version 2.1
http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-sp...
Resources
• Java Persistence with Hibernate Second Edition by Christian Bauer, Gaving King, Gary
Gregory
• Java Platform, ...
Presentation & Cheat
Sheet
Thorben Janssen (@thjanssen123) Prague, 23rd
October 2015
Presentation & Cheat Sheet
• Get this presentation and a handy cheat sheet with all the discussed performance
tuning tips ...
Upcoming SlideShare
Loading in …5
×

Performance Tuning with JPA 2.1 and Hibernate (Geecon Prague 2015)

The Java Persistence API (JPA) is the standard way for Java EE applications to persist data in a database. The application server provides all required libraries and is so easy to use that you can learn it within a few hours. But that changes as soon as it gets more complex and the application needs to support a huge amount of data or if you want to guarantee very short response times.
These requirements can also be fulfilled by JPA and on top of that, there are several Hibernate specific features allowing even more optimizations. Some examples are selecting the right fetch strategy, using different caches and performing bulk operations. But using them efficiently requires far more knowledge.
During this talk, you will get an overview about these and other advanced features that can be used to meet challenging performance requirements. You should already have practical experience with JPA and Hibernate.

Performance Tuning with JPA 2.1 and Hibernate (Geecon Prague 2015)

  1. 1. Performance Tuning with JPA 2.1 and Hibernate Thorben Janssen Thorben Janssen (@thjanssen123), 23rd October 2015
  2. 2. Thorben Janssen • Independent author and trainer • Senior developer and architect @ Qualitype GmbH • CDI 2.0 expert group member • Twitter: @thjanssen123 • Blog: www.thoughts-on-java.org Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  3. 3. Performance Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  4. 4. Performance • Recognize performance problems as early as possible • Typical causes for performance problems • Solving performance problems Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  5. 5. Hibernate Statistics Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  6. 6. Hibernate Statistics • Activate via system property • hibernate.generate_statistics = true • Configure logging • org.hibernate.stat = DEBUG Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  7. 7. Hibernate Statistics • 08:24:10,916 DEBUG [org.hibernate.stat.internal.ConcurrentStatisticsImpl] (default task-1) HHH000117: HQL: SELECT a FROM Author a WHERE a.lastName = :lastName, time: 6ms, rows: 1 Thorben Janssen (@thjanssen123) Prague, 23rd October 2015 Time spend for this query Number of returned rows
  8. 8. Hibernate Statistics 08:08:04,960 INFO [org.hibernate.engine.internal.StatisticalLoggingSessionEventListener] (default task-2) Session Metrics { 1191522 nanoseconds spent acquiring 4 JDBC connections; 433875 nanoseconds spent releasing 4 JDBC connections; 4404058 nanoseconds spent preparing 6 JDBC statements; 12458725 nanoseconds spent executing 6 JDBC statements; 0 nanoseconds spent executing 0 JDBC batches; 0 nanoseconds spent performing 0 L2C puts; 0 nanoseconds spent performing 0 L2C hits; 0 nanoseconds spent performing 0 L2C misses; 586896 nanoseconds spent executing 1 flushes (flushing a total of 2 entities and 2 collections); 39434974 nanoseconds spent executing 1 partial-flushes (flushing a total of 2 entities and 2 collections) Thorben Janssen (@thjanssen123) Prague, 23rd October 2015 Number of statements Cache usage Time spend for statements
  9. 9. Typical causes for performance problems Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  10. 10. Typical Causes • Slow SELECT statements • Wrong FetchType • Load same data multiple times Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  11. 11. Slow SELECT-statements Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  12. 12. Slow SELECTs • In general no „real“ JPA or Hibernate problem • Check generated SQL • Check execution plan of the statement • Check indexes • Optimize SELECT statement • Consider to use a native query Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  13. 13. Native Query • Reasons to use native queries: • JPQL supports only a subset of SQL • Database specific features • Native queries return an Object[] for each row • Needs to be mapped programmatically or declaratively Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  14. 14. SqlResultSetMapping • Declarative mapping of query results @SqlResultSetMapping( name = "myResultMapping ", entities = {@EntityResult(...), …}, classes= {@ConstructorResult (…), …}, columns = {@ColumnResult(…), …} ) this.em.createNativeQuery(“Select …", "myResultMapping") Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  15. 15. SqlResultSetMapping @SqlResultSetMapping( name = "myResultMapping", entities = {@EntityResult( entityClass = Author.class, fields = { @FieldResult(name = "id", column = „autId"), …} ), …}, classes= {@ConstructorResult (…), …}, columns = {@ColumnResult(…), …} ) Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  16. 16. SqlResultSetMapping @SqlResultSetMapping( name = "myResultMapping", entities = {@EntityResult(...), …}, classes= {@ConstructorResult( targetClass = BookPublisherValue.class, columns = { @ColumnResult(name = "title"), …} ), …}, columns = {@ColumnResult(…), …} ) Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  17. 17. SqlResultSetMapping @SqlResultSetMapping( name = "myResultMapping", entities = {@EntityResult(...), …}, classes= {@ConstructorResult(...), …}, columns = {@ColumnResult( name = "bookCount", type = Long.class), …}, ) Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  18. 18. FetchType Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  19. 19. FetchType • Defines when the relationship will be fetched • Static definition in entity mapping @ManyToMany(mappedBy="authors", fetch = FetchType.EAGER) private Set<Book> books; Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  20. 20. FetchType • Lazy • Relationship gets loaded at first access • Default for to-many relationships • Eager • Loads relationships immediately • Default for to-one relationships Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  21. 21. Recommendations • To-many relationships • Stick to the default mapping (FetchType.LAZY) • Use eager fetching for specific queries, if required • To-one relationships • Check individually • Default is fine in most of the cases Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  22. 22. Query Specific Fetching Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  23. 23. Query Specific Fetching • Fetch all required entities with one query • Fetch Joins • @NamedEntityGraph • EntityGraph Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  24. 24. Query Specific Fetching Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  25. 25. Fetch Join Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  26. 26. Fetch Join • Use JOIN FETCH instead of JOIN in JPQL query List<Author> authors = this.em.createQuery( "SELECT DISTINCT a FROM Author a JOIN FETCH a.books b", Author.class).getResultList(); Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  27. 27. Fetch Join • Advantages • Relationships gets loaded in same query • Disadvantages • Requires a special query for each use case • Creates cartesian product Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  28. 28. @NamedEntityGraph Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  29. 29. @NamedEntityGraph • Introduced in JPA 2.1 • Declaratively defines a graph of entities which will be loaded • Graph is query independent Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  30. 30. @NamedEntityGraph • Define a @NamedEntityGraph @NamedEntityGraph( name = "graph.AuthorBooksReviews", attributeNodes = @NamedAttributeNode(value = "books") ) Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  31. 31. @NamedEntityGraph • Define a @NamedEntityGraph @NamedEntityGraph( name = "graph.AuthorBooksReviews", attributeNodes = @NamedAttributeNode(value = "books", subgraph = "books"), subgraphs = @NamedSubgraph( name = "books", attributeNodes = @NamedAttributeNode("reviews"))) Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  32. 32. @NamedEntityGraph • Provide entity graph es hint EntityGraph graph = this.em.getEntityGraph("graph.AuthorBooks"); this.em.createQuery("SELECT DISTINCT a FROM Author a") .setHint("javax.persistence.loadgraph", graph); Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  33. 33. @NamedEntityGraph • Fetch graph • Eager loading for all elements of the graph • Lazy loading for all other attributes • Load graph • Eager loading for all elements of the graph • Loads all other attributes with their defined FetchType • Hibernate always uses a load graph • HHH-8776 Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  34. 34. @NamedEntityGraph • Advantages • Relationships gets loaded in same query • Definition of the graph is independent of the query • Disadvantages • Creates cartesian product Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  35. 35. EntityGraph Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  36. 36. EntityGraph • Introduced in JPA 2.1 • Dynamic version of @NamedEntityGraph • Definition via Java API • Graph is query independent Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  37. 37. EntityGraph • Define and use EntityGraph EntityGraph graph = this.em.createEntityGraph(Author.class); Subgraph<Book> bookSubGraph = graph.addSubgraph(Author_.books); bookSubGraph.addSubgraph(Book_.reviews); this.em.createQuery("SELECT DISTINCT a FROM Author a") .setHint("javax.persistence.loadgraph", graph); Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  38. 38. EntityGraph • Advantages • Relationships gets loaded in same query • Definition of the graph is independent of the query • Dynamic creation at runtime • Disadvantages • Creates cartesian product Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  39. 39. Caching Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  40. 40. Caching Thorben Janssen (@thjanssen123) Prague, 23rd October 2015 1st Level Cache Hibernate Session 1st Level Cache Hibernate Session 2nd Level Cache Query Cache DB
  41. 41. 1st Level Cache Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  42. 42. 1st Level Cache • Activated by default • Linked to the Hibernate session • Stores all entities that were used within a session • Transparent usage Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  43. 43. 2nd Level Cache Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  44. 44. 2nd Level Cache • Session independent entity store • Needs to be activated • persistence.xml or EntityManagerFactory • Transparent usage • PersistenceProvider doesn‘t need to provide it • Not always portable Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  45. 45. 2nd Level Cache • Shared Cache Mode • ALL cache all entities • NONE cache no entities • ENABLE_SELECTIVE cache needs to be activated for specific entities • DISABLE_SELECTIVE cache can be deactivated for specific entities • UNSPECIFIED use default settings of the PersistenceProvider Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  46. 46. 2nd Level Cache • Cache configuration • Cache Retrieve Mode • How to read entities from the cache • Cache Store Mode • How to write entities to the cache • Concurrency Strategy • How to handle concurrent access Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  47. 47. Query Cache Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  48. 48. Query Cache • Stores query results for a query and its parameters • [„FROM Author WHERE id=?“, 1]  [1] • Stores only entity references or scalars • Always use together with 2nd Level Cache Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  49. 49. Query Cache • Hibernate specific • Stores query result session independent • Needs to be activated • persistence.xml: hibernate.cache.use_query_cache = true • Activate caching for a specific query org.hibernate.Query.setCacheable(true) @NamedQuery(… hints = @QueryHint(name="org.hibernate.cacheable", value="true")) Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  50. 50. Recommendations • Only cache data that is seldom updated • Always benchmark the application when adding or changing caching • Use Query Cache together with 2nd Level Cache • Configuration has to fit to each other Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  51. 51. Resources Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  52. 52. Resources • JSR 338: JavaTM Persistence API, Version 2.1 http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index.html • Hibernate Reference Documentation http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ • Hibernate Developer Guide http://docs.jboss.org/hibernate/orm/4.3/devguide/en- US/html/ • Hibernate ORM: Tips, Tricks and Performance Techniques by Brett Meyer http://de.slideshare.net/brmeyer/hibernate-orm-performance-31550150 Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  53. 53. Resources • Java Persistence with Hibernate Second Edition by Christian Bauer, Gaving King, Gary Gregory • Java Platform, Enterprise Edition: The Java EE Tutorial https://docs.oracle.com/javaee/7/tutorial/index.html • Hibernate: Truly Understanding the Second-Level and Query Caches http://www.javalobby.org/java/forums/t48846.html Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  54. 54. Presentation & Cheat Sheet Thorben Janssen (@thjanssen123) Prague, 23rd October 2015
  55. 55. Presentation & Cheat Sheet • Get this presentation and a handy cheat sheet with all the discussed performance tuning tips at http://www.thoughts-on-java.org/geecon2015/ Thorben Janssen (@thjanssen123) Prague, 23rd October 2015

×