Hibernate Spring Boot Performance Practices

repository·master·Indexed 23 days ago

https://github.com/anghelleonard/hibernate-springboot

A collection of best performance practices for Java persistence using Hibernate 5/6 and Spring Boot 2. Covers topics including attribute lazy loading with bytecode enhancement, efficient list chunking, manual and automatic UUID assignment, Spring Data JPA auditing, and avoiding the N+1 select problem when fetching DTOs or joining non-associated entities.

Tokens
101K
Snippets
41
Records
568
Agent score
71%

What's inside hibernate-springboot

  1. Understand RESOURCE_LOCAL vs. JTA transaction types

    master

    This repository provides supporting applications for the article Tackling RESOURCE_LOCAL Vs. JTA Under Java EE Umbrella and Payara Server.

    Developers can use these applications to study the differences between RESOURCE_LOCAL and JTA transaction management within a Java EE environment (specifically using Payara Server) and how they impact Hibernate/JPA operations.

  2. Querying with JpaRepository, EntityManager, and Session

    master

    This project demonstrates three different ways to execute queries in a Spring Boot application using Hibernate/JPA:

    1. JpaRepository: Use the @Query annotation for JPQL/SQL or leverage Spring Data's automatic query creation (method name derivation).
    2. EntityManager: Use the createQuery() method to execute JPQL queries.
    3. Session: Use the createQuery() method (Hibernate Session API) to execute queries.

    For more detailed implementation examples, refer to the HibernateSpringBootQueryFetching module in this repository.

  3. JDBC Batching a Big JSON File to MySQL via ForkJoinPool and HikariCP

    master

    This Spring Boot application demonstrates how to efficiently ingest large JSON files (200,000+ lines) into a MySQL database using the json data type. It leverages ForkJoinPool for parallel processing, JdbcTemplate for batching, and HikariCP for connection pooling.

    Implementation Logic

    1. Read the JSON file content into a List.
    2. Use a recursive decomposition strategy: the list is halved into subtasks until the list size is smaller than the defined batch size (e.g., 30).
    3. Execute batch inserts using the subtasks within a ForkJoinPool.
    4. Use StopWatch to measure the total transfer time.
  4. Implement advanced search using the Specification API

    master

    This project demonstrates how to implement advanced searching in Spring Boot using the JPA Specification API.

    Key capabilities include:

    • Generic Specifications: Implementing a generic Specification that accepts search filters to fetch result sets.
    • Pagination: Full support for paginated search results.
    • Compound Filters: The ability to chain expressions using logical AND and OR operators to create complex search criteria.

    Note: While the current implementation supports basic chaining, it can be extended to support bracketed expressions (e.g., (x AND y) OR (x AND z)), additional operations, and custom condition parsers.

  5. Understand Spring Transaction Propagation

    master

    The HibernateSpringBootTransactionPropagation directory contains several Spring Boot applications designed to demonstrate how different Spring transaction propagation behaviors work in practice. Each application serves as a practical example of how transactions interact when methods are called within different propagation contexts.

    For a comprehensive understanding of these patterns and how they relate to persistence best practices, it is recommended to refer to the book Spring Boot Persistence Best Practices.

  6. How to efficiently chunk a Java List

    master

    Chunking a large List into smaller sublists of a specific size is a common requirement, particularly when implementing concurrent batch processing where each thread requires a subset of items.

    This project demonstrates 6 different ways to implement list chunking in plain Java, as well as using third-party libraries. The choice of implementation involves a trade-off between implementation speed (how quickly you can write the code) and execution speed (how fast the code runs).

    Implementation Options

    1. Third-Party Libraries (Fastest to implement):
      • Google Guava: Use Lists.partition(List list, int size).
      • Apache Commons Collections: Use ListUtils.partition(List list, int size).
    2. Plain Java:
      • Grouping Collectors: Simple and fast to write, but performs poorly in terms of execution speed.
      • List.subList() (Fastest execution): The Chunk.java class in this repository provides the most performant implementation by leveraging the built-in List.subList() method.
  7. Efficiently fetch Spring Projections with @ManyToOne or @OneToOne associations

    master

    This project demonstrates different approaches to fetching Spring projections that include @ManyToOne or @OneToOne associations. The primary goal is to optimize performance when dealing with nested data structures in Spring Data JPA.

    Key Performance Insight: Fetching raw data is identified as the fastest approach for retrieving these projections.

  8. Batch Inserts in Spring Boot via CompletableFuture

    master
    This implementation demonstrates how to perform batch inserts in a Spring Boot application using CompletableFuture. The approach utilizes an Executor configured with a thread count equal to the number of available CPU cores to parallelize the insertion process. This pattern is designed to optimize throughput during large-scale data persistence tasks.
  9. How to obtain auto-generated keys in Spring Boot

    master

    This project demonstrates three different ways to retrieve database auto-generated primary keys after an insert operation:

    1. JPA Style: Use the standard JPA approach where the generated ID is automatically populated in the entity, which you can then retrieve using the entity's getId() method.
    2. JDBC Style via JdbcTemplate: Use Spring's JdbcTemplate to execute an insert and capture the generated keys.
    3. JDBC Style via SimpleJdbcInsert: Use SimpleJdbcInsert for a more streamlined JDBC approach to handle auto-generated keys.
  10. Direct fetching via Spring Data, JPA EntityManager, and Hibernate Session

    master

    This module provides examples of how to perform direct fetching of entities using three different layers of the Java persistence stack. Depending on the abstraction level you are working with, use the following methods:

    • Spring Data JPA: Use findById() within your repository interfaces.
    • JPA (Java Persistence API): Use find() via the EntityManager.
    • Hibernate: Use get() via the Hibernate Session.
  11. Use JPA JOINED inheritance strategy and the Visitor design pattern

    master
    This project demonstrates how to implement the JPA JOINED inheritance strategy in conjunction with the Visitor design pattern. The implementation allows for defining multiple visitors and applying specific ones to an inheritance hierarchy to perform operations on different subclasses without modifying the classes themselves.