How to map a @ManyToOne association using a non-Primary Key column with JPA and Hibernate

Introduction

While answering questions on the Hibernate forum, I stumbled on the following question about using the @ManyToOne annotation when the Foreign Key column on the client side references a non-Primary Key column on the parent side.

In this article, you are going to see how to use the @JoinColumn annotation in order to accommodate non-Primary Key many-to-one associations.

Continue reading “How to map a @ManyToOne association using a non-Primary Key column with JPA and Hibernate”

Advertisements

The best way to map a many-to-many association with extra columns when using JPA and Hibernate

Introduction

For a simple many-to-many database relationship, you can use the @ManyToMany JPA annotation and, therefore, hide the join table.

However, sometimes you need more than the two Foreign Key columns in the join table, and, for this purpose, you need to replace the @ManyToMany association with two bidirectional @OneToMany associations. Unlike unidirectional @OneToMany, the bidirectional relationship is the best way to map a one-to-many database relationship that requires a collection of Child elements on the parent side

In this article, we are going to see how you can map a many-to-many database relationship using an intermediary entity for the join table. This way, we can map additional columns that would be otherwise impossible to persist using the @ManyToMany JPA annotation.

Continue reading “The best way to map a many-to-many association with extra columns when using JPA and Hibernate”

What’s new in JPA 2.2 – Stream the result of a Query execution

Introduction

Now that the JPA 2.2 Review Ballot was approved, let’s start analyzing some of the new additions to the standard which have been supported by Hibernate for quite some time already.

In this article, we are going to see how Stream query results are supported by Hibernate and the caveats of using database cursors just to limit the amount of data that needs to be fetched.

Continue reading “What’s new in JPA 2.2 – Stream the result of a Query execution”

What’s new in JPA 2.2 – Java 8 Date and Time Types

Introduction

Now that the JPA 2.2 Review Ballot was approved, let’s start analyzing some of the new additions to the standard which have been supported by Hibernate for quite some time already.

In this article, we are going to see how Java 8 Date/Time API is supported and which types you need to use depending on your business case requirements.

Continue reading “What’s new in JPA 2.2 – Java 8 Date and Time Types”

The best way to map the @DiscriminatorColumn with JPA and Hibernate

Introduction

As previously explained, the SINGLE_TABLE inheritance is the most efficient entity inheritance strategy.

However, for JPQL query such as this one:

List<Post> posts = entityManager
.createQuery(
    "select p " +
    "from Post p " +
    "where p.board = :board", Post.class)
.setParameter("board", board)
.getResultList();

Hibernate generates a SQL query which filters by the associated discriminator column (e.g. DTYPE by default):

SELECT t.id AS id2_1_,
       t.board_id AS board_id8_1_,
       t.createdOn AS createdO3_1_,
       t.owner AS owner4_1_,
       t.title AS title5_1_,
       t.content AS content6_1_
FROM   topic t
WHERE  t.DTYPE = 'Post'
       AND t.board_id = 1

So, because we are filtering by the discriminator column, we might want to index it or include it to speed up queries.

However, the default STRING DiscriminatorType expects a VARCHAR column that must hold the longest entity subclass name. For the Announcement class, we need at least 12 bytes to store the entity class name while for the Post entity, 4 bytes are required.

If the discriminator type column is indexed and we store 1 million Announcement and 100 million Post entities, the index will require 393 MB (12 + 400 million bytes). On the other hand, if the discriminator column is a TINYINT (only 1 byte is needed to store a discriminator value), we need only 96 MB (1 + 100 million bytes).

In this article, I’m going to explain how you can get the most out of the INTEGER DiscriminatorType while still retaining the descriptiveness of the default STRING DiscriminatorType.

Continue reading “The best way to map the @DiscriminatorColumn with JPA and Hibernate”