Mapping Entity relationships with JPA annotations

We will look at some practical examples of how to wire in Entity relationships using standard JPA annotations.

Generating Primary Key Id from Sequence

Consider the below SQL:

I would like to auto-generate the ID of GENRE from the SEQ_GENRE_ID.

This is how my Entity would look like:

Here, the @SequenceGenerator contains the name of the sequence used for ID generation. This can be ignored for DB like MySQL, which has support for AUTO GENERATION at the table level itself. The @GeneratedValue has the strategy used to generate the value.

Simple One to One Relationship

Consider the below tables:

Chapter

Section

The simple One-to-One can be wired up by using the below 2 annotations:

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = “content_id”)
private Section contents;

Specify the name of the column in the CHAPTER table which is the FOREIGN KEY to the SECTION table.

One to Many Relationship using a Mapping table

Consider the below entity:

In terms of SQL, we can have a main table called BOOK and then a mapping table called BOOK_GENRE. This mapping table would contain the IDs of BOOK and GENRE tables.

This relationship can be represented by:

@OneToMany(fetch = FetchType.EAGER)

@JoinTable(name = “BOOK_GENRE”, joinColumns = @JoinColumn(name = “book_id”, referencedColumnName = “id”), inverseJoinColumns = @JoinColumn(name = “genre_id”, referencedColumnName = “id”))

The @JoinTable takes in the name of the Mapping table. It has the below 2 attributes:

  1. joinColumns: You need to provide the FOREIGN KEY from the owning part of the relationship, in this case,  BOOK
  2. inverseJoinColumns: You need to provide the FOREIGN KEY of the non-owning side of the entity, in this case, GENRE

Saving Entity relationships

By default, none of the Entity relations are inserted or updated. You need to explicitly specify the cascade attribute in the OneToOne or OneToMany annotation.

@OneToOne(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name = “main_chapter_id”)
private Chapter mainChapter;

If you do not want to save the Entity, do not specify the cascade attribute:

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = “author_id”)
private Author author;

Sources

A working example can be found here:

https://github.com/paawak/blog/tree/master/code/one-to-many-example-2

Leave a Reply

Your email address will not be published. Required fields are marked *