Synchronization Methods for Many-To-Many Associations

The many-to-many association is a common thing in data modeling. In JPA entities, it is implemented as collections that store associated entities from the other side of the association. To keep collections consistent on both sides, developers usually implement data synchronization methods. This article will highlight common issues that happen when adding synchronized methods for many-to-many bidirectional associations in JPA entities.

Many-To-Many Bidirectional Associations: Why Synchronize?

Before speaking about sync methods, let's look at bidirectional associations and their implementation in JPA in detail. Imagine a blog application where we can mark every post with several tags. We can make two JPA entities for this application: Post and Tag with appropriate attributes like ID, text, etc. Now we need to establish the association between one post and many tags. To do this, let's define a tags attribute on the Post entity, the type of this attribute is Set<Tag>. Notice that each tag can be reused for more than one post. In this case, we can create the posts attribute of type Set<Post> in the Tag entity. This is the bidirectional many-to-many association: we have references to several entities on both sides of the association. And now, our data model looks like this:

Simplify Java Persistence Implementation With Kotlin on Quarkus

For decades, developers have struggled with optimizing persistence layer implementation in terms of storing business data, retrieving relevant data quickly, and — most importantly — simplifying data transaction logic regardless of programming languages.

Fortunately, this challenge triggered the invention of Java ecosystems in which developers can implement the Java Persistence API (JPA). For instance, Hibernate Object-Relational Mapper (ORM) with Panache is the standard framework for JPA implementation in the Java ecosystem.

The Ultimate Guide on Client-Generated IDs in JPA Entities

ID generation in the client instead of the database is the only option for distributed apps. But generating unique IDs in such apps is hard. And it's essential to generate them properly because JPA will use IDs to define entity states. The safest option is to use UUIDs and Hibernate's generators, but there are more options starting from custom generators to dedicated ID generation servers.

In the previous article, we discussed server-generated IDs for JPA entities. All the ID generation strategies described in the article are based on one fundamental principle: there is a single point that is responsible for generating IDs: a database. This principle might become a challenge: we depend on a particular storage system, so switching to another (e.g., from PostgreSQL to Cassandra) might be a problem. Also, this approach does not work for distributed applications where we can have several DB instances deployed on several data centers in several time zones. 

Getting Started With JPA/Hibernate

JPA was born as the acronym for Java Persistence API. When Java EE was donated to the Eclipse Foundation under the Jakarta EE project, the name of the API changed to Jakarta Persistence but the term JPA is still in use. JPA solves the object-relational impedance mismatch by allowing you to map Java objects to database tables and is one of the most (if not the most) used persistence frameworks for Java.

JPA is an API specification that someone can implement–JPA providers or implementations. The most popular JPA implementation is Hibernate ORM. You can use Hibernate ORM without JPA or through JPA. One potential advantage of using it with JPA is that you can move between implementations if you want (something I have never seen happening, though). Another advantage is that someone with experience in, say EclipseLink or Apache OpenJPA, then they can use at least part of that experience when moving to Hibernate.

Inheritance vs. Composition in JPA

Introduction

«Don't repeat yourself» or «DRY». Developers try to adhere to this principle during software development. It helps to avoid redundant code writing and, as a result, simplifies its maintainability in the future. But how to achieve this principle in the JPA world?

There are two approaches: Inheritance and Composition. Both have their pros and cons. Let's figure out what they are on the not quite "real-world" but representative example.

Simplify Java persistence using Quarkus and Hibernate Reactive

This tutorial shows how you can simplify reactive Java applications that persist data using the Hibernate ORM with Panache extension in Quarkus.

Business applications preserve valuable business data in persistence stores such as relational databases. The application's presentation layer usually showcases the data for multiple uses, such as inventory, shopping, subscription, and monitoring. Java provides a core feature, the Java Persistence API (JPA), to manage persistent objects using object-relational mapping (ORM) with databases such as PostgreSQL, MySQL, and Microsoft's SQL Server. However, even when using JPA annotations, you must implement the JPA specifications to handle data transactions.

The First Annual Recap From JPA Buddy

2021 is almost over. This year JPA Buddy met its first user and grew up into one of the most rated plugins in the IntelliJ IDEA marketplace. In this article, we decided to share a short story behind JPA Buddy, its achievements in 2021, and plans for 2022.

History

Let us start with a few words about the history behind JPA Buddy. The idea of JPA Buddy as a plugin for IntelliJ IDEA was born back in 2019. Roots come from another product called Jmix (previously CUBA Platform). Jmix is both a framework and specialized tooling for productive business application development. As you may guess its data layer is built over JPA; it's tooling, Jmix Studio, provides great facilities to express your data model via JPA entities nearly without manual coding.

Think Twice Whether You Need Hibernate

I often saw how people included hibernating into a project, not really thinking about whether they really needed it. And after some time, when the service grew, they began to wonder if this was a mistake.

Let’s try to think ahead of what the general pros and cons of Hibernate are so that we can better determine the next time whether we need to add this dependency in a new microservice. Perhaps it makes sense to get by with simple Spring JDBC, without all that JPA complexity?

Best Practices of Using JPA (Hibernate) With Kotlin

Kotlin is great: it’s more concise and expressive than Java, it allows for safer code, and offers seamless interoperability with Java. The latter allows developers to migrate their projects to Kotlin without having to rewrite the entire codebase. Such migrations are one of the reasons why we might have to work with JPA in Kotlin. Picking JPA for a fresh Kotlin application also makes sense, as it is a mature technology familiar to the developers.

There is no JPA without entities, and defining them in Kotlin comes with some caveats. Let’s look at how to avoid the common pitfalls and make the most of using Kotlin. Spoiler alert: data classes are not the best option for entity classes.

This article will be mostly focused on Hibernate as it is undoubtedly the leader among all JPA implementations.

Lombok and JPA: What Could Go Wrong?

Lombok is a great tool that makes your Java code concise and clean. However, there are a few things to consider when using it with JPA. In this article, we’ll look at how the misuse of Lombok can hurt the performance of JPA applications or even crash them, and how to avoid that but still gain the benefits of using Lombok.

We develop JPA Buddy – a plugin for IntelliJ IDEA designed to make the use of JPA easier. Before writing a single line of code for it, we went through a ton of projects on GitHub to understand how people work with JPA. Turns out, a lot of them use Lombok for their entities.

Spring Data JPA + QueryDSL: Taking the Best From Both Worlds

You can find the full project on GitHub using this link. There is a simple SpringBoot application with configured MySQL data source and initial database structure described as a Flyway migration.

Here we will concentrate only on the building persistence layer. As we deal with the relational database we will rely on the JPA specification. Let’s take a simple entity model like Author/Book as an example:

A (Definitive?) Guide on LazyInitializationException

Posts that have been written about Hibernate's LazyInitializationException could probably fill whole books. Yet, I believe each of them focuses on a particular aspect of it: some on a specific solution, some on how to solve it with Spring Boot, etc. I'd like this post to be the definitive guide on the subject, even though I'm pretty sure it won't. At least, I'll be able to point others to it.

The Root Cause

Whether you love or hate ORM frameworks in general, they are nonetheless pretty common in the Java ecosystem. JPA is the ORM standard and part of the Jakarta EE specifications. Hibernate is its most widespread implementation: for example, it's the default in Spring Boot.

Hibernate Naming Strategies: JPA Specification vs Spring Boot Opinionation

Each time we inject a dependency into our project, we sign a contract, which often has lots of hidden things "written in the fine print". In this article, we will take a look at something you could miss when signing a tripartite contract between you, Hibernate, and Spring Boot. We will talk about naming strategies.

Defaults in JPA Naming

The ultimate rule about defaults: they must be intuitive. Let's check if this rule applies to a standard Spring Boot application with default configuration using Hibernate as a JPA implementation. Imagine you have an entity "PetType". Let's guess what table name in the database it is associated with.