Persistence with JPA and Hibernate is one of the main topics in my daily work and on this blog. This page provides a curated list of some of the best and most popular posts in the categories:
- Most Popular
- JPA 2.2
- Hibernate 5
- JPA 2.1
- Performance
- General Concepts
- Mapping Definitions
- Configuration
- Native SQL Queries
- Create and Update Database Schemata
- Hibernate Envers
- Hibernate Search
Most Popular
I covered a broad range of Hibernate and JPA topics, from beginner tutorials about writing JPQL queries, over Hibernate best practices to advanced topics, like query hints.
Here are some of the most popular posts:
- Hibernate Best Practices
- 7 Tips to boost your Hibernate performance
- Ultimate Guide to JPQL Queries with JPA and Hibernate
- Native Queries – How to call native SQL queries with JPA
- Hibernate Logging Guide – Use the right config for development and production
- 11 JPA and Hibernate query hints every developer should know
- JPA 2.1 – 12 features every developer should know
JPA 2.2
JPA 2.2 was just a small maintenance release, but it brought a few interesting changes. For most developers, the added support for Java’s Date and Time API and new getResultStream() method were probably the most important changes.
- How To Map The Date And Time API with JPA 2.2
- JPA 2.2 Introduces @Repeatable Annotations
- JPA 2.2’s new getResultStream() method and how you should NOT use it
Hibernate 5
Hibernate 5 brought a lot of changes and additions to the existing APIs. The development team not only introduced the support for Java 8, but they also extended the existing APIs to make the implementation of common use cases easier.
I listed the 5 most important changes in 5 new features in Hibernate 5 every developer should know.
Java 8 Support
- Benefits of @Repeatable annotations in Hibernate 5.2
- How to get query results as a Stream with Hibernate 5.2
- How to persist LocalDateTime & Co with Hibernate
- How to use Java 8’s Optional with Hibernate
Improved Support for Common Use Cases
- How to persist creation and update timestamps with Hibernate
- How to fetch multiple entities by their primary key
- How to join unrelated entities with JPA and Hibernate
JPA 2.1
JPA 2.1 introduced a set of new features to the specification to make the work with a relational database easier and more efficient. You can get an overview of all the new features in JPA 2.1 – 12 features every developer should know.
Or if you already know what you are searching for, have a look at the following list of JPA 2.1 related articles.
Attribute Converter
- JPA 2.1 – How to implement an Attribute Converter
- How to persist LocalDate and LocalDateTime with JPA
- JPA 2.1 Attribute Converter – The better way to persist enums
- How to use a JPA Attribute Converter to encrypt your data
Entity Graphs
- JPA 2.1 Entity Graph – Part 1: Named entity graphs
- JPA 2.1 Entity Graph – Part 2: Define lazy/eager loading at runtime
Stored Procedure Calls
- How to Call a Stored Procedure with a @NamedStoredProcedureQuery
- How to Define a Stored Procedure Call at Runtime
Custom Database Functions
Criteria API
Constructor Result Mappings
Generating DB Schema
Create Named Queries At Runtime
Performance
Implementing your persistence tier with Hibernate is quite easy and as the most popular JPA implementation also the way to go for Java EE applications. But what starts as nice and easy often turns out to be an issue as soon as the requirements get more challenging. You need to know more than just the basics of Hibernate and JPA to create an application that performs well on a huge database or under high load.
- 7 Tips to Boost your Hibernate Performance
- Free Mini Course: How to find and fix n+1 select issues with Hibernate
- 5 Tips to Write Efficient Queries with JPA and Hibernate
- 5 Ways to Initialize Lazy Relations and When to Use Them
- How to Activate Hibernate Statistics to Analyze Performance Issues
- How to Perform a Bulk Update with a Native SQL query
- Criteria Update/Delete – The Easy Way to Implement Bulk Operations with JPA 2.1
- 5 Common Hibernate Mistakes That Cause Dozens of Unexpected Queries
- 10 Common Hibernate Mistakes That Cripple Your Performance
General Concepts
If you’re new to JPA and Hibernate, you might want to start with some basic articles that explain the general concepts and show you when JPA and Hibernate are a good fit for your project.
- 5 Reasons to Use JPA and Hibernate
- What’s the difference between JPA, Hibernate and EclipseLink
- Should you use JPA for your next Project?
- Getting Started With Hibernate
- What’s the difference between persist, save, merge and update? Which one should you use?
- Why, When and How to Use DTO Projections with JPA and Hibernate
- Entities or DTOs – When should you use which projection?
- 5 Things You Need to Know When Using Hibernate with Mysql
- Hibernate with PostgreSQL – 6 things you need to know
- Ordering vs Sorting with Hibernate – What should you use?
- 8 Ways to use the features of your database with Hibernate
- How to implement a soft delete with Hibernate
- How to persist creation and update timestamps with Hibernate
- Is your query too complex for JPA and Hibernate?
- Create type-safe queries with the JPA static metamodel
- Hibernate Tips: How to automatically add Metamodel classes to your project
- Implementing the Repository pattern with JPA and Hibernate
Entity Mappings
Hibernate and JPA support lots of different mapping annotations that allow you to map complex domain and table models.
General
- Complete Guide: Inheritance strategies with JPA and Hibernate
- Composition vs. Inheritance with JPA and Hibernate
Identifier Mappings
- How to Generate Primary Keys with JPA and Hibernate
- How to Generate UUIDs as Primary Keys with Hibernate
- @NaturalId – A good way to Persist Natural IDs with Hibernate?
Attribute Mappings
- How to map a java.util.Date to a Database Column
- How to persist LocalDateTime & Co with Hibernate
- How to persist LocalDate and LocalDateTime with JPA
- How to map an Enum to a Database Column
- JPA 2.1 Attribute Converter – The better way to persist enums
- How to map an Entity Attribute to an Optional
Association Mappings
- Ultimate Guide – Association Mappings with JPA and Hibernate
- Introduction to JPA FetchTypes
- How to Choose the Most Efficient Data Type for To-Many Associations – Bag vs. List vs. Set
- Best Practices for Many-To-One and One-To-Many Association Mappings
- Why you should avoid CascadeType.REMOVE for to-many associations and what to do instead
- How to map an association as a java.util.Map
- How to persist additional attributes for a relationship with JPA and Hibernate
Custom Data Types
- JPA 2.1 – How to implement an Attribute Converter
- How to persist LocalDate and LocalDateTime with JPA
- JPA 2.1 Attribute Converter – The better way to persist enums
- How to use PostgreSQL’s JSONB data type with Hibernate
Configuration
JPA and Hibernate use a huge set of defaults so that you need almost no configuration. The only configuration you need to provide are a few parameters in the persistence.xml file and a logging configuration. You can learn more about them here:
- A Beginner’s Guide to JPA’s persistence.xml
- Mapping Definitions in JPA and Hibernate – Annotations, XML or both?
- Hibernate Logging Guide – Use the right config for development and production
Native SQL Queries
The Java Persistence Query Language (JPQL) is the most common way to query data from a database with JPA. But it supports only a small subset of the SQL standard, and it also provides no support for database specific features.
If queries get complex, these limitations become an issue, and you need to take a different approach to retrieve the required information efficiently. In these situations, native SQL queries are most often the best solution. You can similarly use them as JPQL queries, and they allow you to use all SQL features supported by your database.
- How to call native SQL queries with JPA and Hibernate
- How to perform bulk updates with native SQL queries
Result Mappings
One of the downsides of native SQL queries is, that they return a List<Object[]> and that you need to cast all these Objects into the right type. An easy solution for it are Result Set Mappings which I explained in a series of blog posts:
- Result Set Mapping: The Basics
- Result Set Mapping: Complex Mappings
- Result Set Mapping: Constructor Result Mappings
- Result Set Mapping: Hibernate specific features
Building Native Queries With jOOQ
jOOQ provides a powerful DSL that enables you to build fully-featured SQL queries. If you want to use it together with Hibernate, you can build your query with jOOQ and execute it within your current persistence context as a native SQL query.
Create and Update Database Schemata
If you ever shipped an application to hundreds of customers or updated a production database without causing downtime, you know that it isn’t as easy as it might seem. A good migration process requires much more effort, and skills than a lot of developers expect. Here are a few articles that might be helpful.
Schema generation with JPA and Hibernate
You can use Hibernate and JPA to generate your database schema based on entity mappings or SQL scripts. I don’t recommend to use this approach for production, but it helps to create your first database scripts and can be a good option to set up test systems.
- Should you Create or Generate your Table Model?
- Standardizes Schema Generation and Data Loading with JPA 2.1
Version-based database migration tools
If you need to update the database of your production system, you should prefer a version-based migration approach. The general idea is simple: You apply the same versioning approach for your source code and database.
There are several tools available that help you implement a version-based database migration. One of them is Liquibase:
- Version-Based Database Migration with Liquibase – Getting Started
- Version-Based Database Migration with Liquibase – Update an Existing Database
- How To Implement Automatic Database Updates By Integrating Liquibase
Flyway is another tool to implement version-based database migrations:
- Getting Started with Flyway and Version-Based Database Migration
- How to Use Java-Based Migrations and Callbacks to Implement Complex Database Migrations With Flyway
Updating a schema without causing downtime
Updating a schema while your application is offline is quite simple. You just perform all required operations, restart the application and hope that everything works fine.
But that’s no longer the case if your customers don’t accept any downtime. You then need a complex, multi-step migration process that enables the old and the new version of your application to use the same database. I show you how to do that in Update your Database Schema Without Downtime.
Hibernate Envers
A lot of business applications require an audit log that documents all changes that were performed on the managed data. There are lots of different options to implement such a log. One of them is Hibernate Envers. It just takes a few annotations to document all changes in the audit tables, and Envers also provides a powerful API for extracting information from your audit log.
- Hibernate Envers – Getting Started
- Hibernate Envers – Extract Data from your Audit Log with the AuditReader
- Hibernate Envers – Extend the Standard Revision to Store Additional User Information
- How to Implement Conditional Auditing with Hibernate Envers
Hibernate Search
Full-text search has become a common requirement for modern enterprise applications, and there are several good implementations available that provide powerful indexing and search capabilities. But one important question remains when you decide to add one of them to your application: How do you keep the full-text search indexes in sync with of your database?
Hibernate Search provides an easier solution. It integrates with Hibernate ORM, updates the Lucene and Elasticsearch indexes transparently and provides a query DSL for full-text queries.