[JAVA] Summarize the main points of getting started with JPA learned with Hibernate

1. Motivation

The company is developing a web application using the struts2 framework. This application uses Hibernate instead of JDBC for DB access, but I was in trouble because I didn't have any knowledge. Meanwhile, I came across the following good books, so I understood the contents and summarized the main points.

--Introduction to JPA for database access learned with Seasar2 and Hibernate Written by Toshihiro Nakamura, published by Mainichi Communications

2. Keywords that appear

3. Glossary

a. O / R mapping

Associate a Java object (Object) with data on a relational database (Relational). A major feature of JPA is that it has an O / R mapping function. On the other hand, JDBC (*) needs to program the association between the object and the DB. (The program becomes complicated.)


b. JPA(Java Persistence API) API included in Java EE (*). JPA is only a specification, and there are multiple products that implement JPA, and the representatives are Hibernate, TopLink Essentials, and Open JPA. Environmental aspect: Can be used with Java EE and Java SE. JDK 5.0 or above is required.


-[Introduction to Java] Explains the differences between Java SE and EE and JRE / JDK in the world's easiest way https://www.sejuku.net/blog/12902 --Differences between Java and Java EE in Eclipse https://qiita.com/kojocho/items/b5d3646012b7a6411c3d

c. Hibernate

An open source JPA implementation provided by Red Hat. To use Hibernate as a JPA implementation, you need 3 products: Hibernate Core, Hibernate Annotations, and Hibernate Entity Manager. Compared with JDBC, the following 4 processes are unnecessary. (Details will be described later)

--SQL statement --Refilling data from ResultSet --Resource close --Exception handling

4. How to implement data acquisition / update / addition / deletion

JPA associates a table with a Java class by O / R mapping and treats one record of the table as one instance of Java class. This time. Java classes are called ** entity classes **, their instances are called ** entities **, and entities are handled through ** EntityManager **.

When an application requests to get an entity, EntityManager first checks if it is cached in the persistent context and returns the cached entity if the cache exists.

The image looks like this.

画像1.png

Data acquisition

There are two types of entity acquisition methods: primary key acquisition (1) and JPQL (2) acquisition.

(1) Acquisition by entity

To get an entity with a primary key, use EntityManager's *** find method ***.

item Description
argument Pass the entity class as the first argument and the primary key value as the second argument
Return value If an entity exists, that entity.
Null if it does not exist
public void findById() throws Exception{
	// EntityManager(em)Is injected with DI
	//Get record (entity) whose primary key of Emp class (table) is "1"
	Emp emp = em.find(Emp.class, 1L);
}
(2) Acquisition by JPQL

In the case where the entity is not acquired by specifying the primary key, the find method of EntityManager cannot be used and it is necessary to implement it in JPQL. JPQL is JPA's own query language and is completely different from SQL. In JPQL, you can create a Query object by passing an argument to the *** createQuery method *** of EntityManager. You can pass bind variable parameters and paging information to Query. Entity can be obtained by executing getResultList method and getSingleResult method of Query.

item Description
argument jpql (inquiry text)
Return value If there is a record that matches the condition, the matching entity list
Empty list if it does not exist (size = 0)

b. Data update

You can update the data by getting the entity you want to update with EntityManager and changing the state of that entity. EntityManager manages the original data before the change, compares the original data with the current data at an appropriate timing, and automatically detects the update. When it detects that an entity has been updated, an Update statement is automatically issued.

(The condition of the version column (described later) used in optimistic exclusive control is automatically added to the Update statement issued at this time.)

public void updateEntity() throws Exception{
	// EntityManager(em)Is injected with DI
	//Get record (entity) whose primary key of Emp class (table) is "1"
	Emp emp = em.find(Emp.class, 1L);
    emp.setEmpName("NEWNAME");
    //Update statement is issued automatically
}

c. Add data

To add an entity, pass the newly created entity to the *** persist method *** of EntityManager. If @GeneratedValue annotation is specified in the primary key record in the entity class definition of the operation target, it is automatically set without setting the value in the primary key element.

public void persistEntity() throws Exception{
	// EntityManager(em)Is injected with DI
	//Generate the following Emp entity
    Emp emp = new Emp();
    emp.setEmpNo (123);
    emp.setEnpName("123Name");
    em.persist(emp);
    //Insert statement is issued automatically
}

d. Delete data

To delete an entity, pass the entity you want to remove to the *** remove method *** of EntityManager. EntityManager issues a SQL Delete statement at the right time.

(The condition of the version column (described later) used in optimistic exclusive control is automatically added to the Delete statement issued at this time.)

public void removeEntity() throws Exception{
	// EntityManager(em)Is injected with DI
	//Delete the following entity
    em.remove(emp);
    //Delete statement is issued automatically
}

5. O / R mapping

a. Annotation

The annotations required for O / R mapping are as follows. All of these annotations belong to the "javax.persistence" package.

*** For the fetch attribute of @ManyToOne, @OneToMany, and @OneToOne, basically specify "fetchType.LAZY" (described later). *** ***

No Annotation Specified location Meaning to represent
1 @Entity class Being an entity
Entity name is a name used in JPQL to identify an entity in the Java world.
Example:@Entity(name = "Hoge")
2 @Id field Being a primary key
3 @Transient field Be non-permanent
Give when you do not want to associate with database columns
4 @GeneratedValue field Automatically generate primary key value
5 @ManyToOne field The relationship is many-to-one
6 @OneToMany field The relationship is one-to-many
7 @OneToOne field The relationship is one-to-one
8 @Table class Specify the table to be mapped
9 @Column field Specify that it is a mapping target column
Columns without NOT NULL constraints must use a wrapper type to represent NULL
10 @JoinColumn field Specify the source column and the destination column
11 @SequenceGenerator field Definition of the sequence that generates the primary key
12 @TableGenerator field Definition of the table that generates the primary key
13 @Version field Must be a version number field for using optimistic concurrency control (discussed below)
Field type should be Integer type or Long type

b. Lazy loading

When a table has a parent-child configuration, the child table is not acquired when the parent table is acquired, but is acquired when needed (on the back side).

Since the fetch attribute of @ManyToOne, @OneToMany, and @OneToOne defaults to "fetchType.EAGER", use the delayed loading "fetchType.LAZY" unless you have a specific intention.

C. N + 1 problem

Issue a SELECT statement once to get N records (parent entities) from any table, N records issue a SELECT statement once to get the related data (child entity), a total of N times. Please note that a large amount of SQL will be issued unintentionally. There are the following two solutions.

--Using JOIN FETCH with JPQL -Use @Fetch annotation


reference

--JPA performance problems and countermeasures https://qiita.com/itagakishintaro/items/04b6933a29e92f8ee4b7

  1. JPQL JPQL is interpreted by the JPA implementation, converted to SQL suitable for the database to be used, and then executed. SQL has dialects for each database, but by using JPQL, some differences between dialects can be absorbed.

a. Grammar and terminology

(1) Entity name and identification variable

Specify the entity name (≠ table name) in the FROM section of JPQL. The identification variable (hereinafter "e" in SQL) is declared after the entity name, and the extraction items etc. are specified using it.

select e from Employee e;
(2) Fetch join

With lazy loading applied, child entities are only retrieved when needed. On the other hand, if it is known that child entities are also needed from the beginning, it is more efficient to get them at the same time with one SQL. In such cases, use *** fetch join ***. The SQL using fetch join is as follows.

select distinct d d from Department d inner join fetch d.employees where d.name = "ABC";

7. Entity life cycle

a. Four states of the entity

Once retrieved, the entity is managed in a persistent context. Within the persistent context, it is managed in the following four states. These states change due to EntityManager method execution and persistence context termination, and are called *** entity lifecycle ***. The figure is as follows.

--New The new entity remains the new entity unless you specify the EntityManager's persist and merge methods.

--Managed When an entity is acquired using EntityManager's find method or JPQL, when the entity is passed to the merge method by EntityManager's persist method, the entity is managed in a persistent context. Persistent field changes to managed entities are automatically detected.

--Detached Even if you make changes to the separated entity, the changes will not be reflected in the persistence context unless the entity is remanaged by the merge method of EntityManager.

--Removed If you pass the managed entity to the remove method of EntityManager, it will be removed from the persistence context.

画像2.png

b. Database synchronization

EntityManager reflects managed entities and deleted entities in the database. This process is called *** database synchronization ***. Synchronization writes entity change information stored in the persistence context to the database.

The default timing for database synchronization is as follows:

--When the flush method of EntityManager is called --Just before the transaction is committed --Just before executing the inquiry

8. JPA optimistic exclusive control

Exclusive control includes pessimistic exclusive control that locks specific data and prohibits CRUD from other transactions, and optimistic exclusive control that does not lock data and fails the other processing when updates conflict. ..

JPA can realize optimistic exclusive control based on this version number by preparing an integer type column that manages the version number (@Version assignment) in the database.


* Extra edition * Things that are useful to know

--I want to check the SQL issued by Hibernate in the log → Set "true" in the hibernate.show_sql property of persistence.xml (*).

<property name = "hibernate.show_sql" value = "true" />

--I want to format and display the SQL in the log issued by Hibernate → Set "true" in the hibernate.format_sql property of persistence.xml (*).

<property name = "hibernate.format_sql" value = "true" />


Recommended Posts

Summarize the main points of getting started with JPA learned with Hibernate
Getting started with the JVM's GC mechanism
Getting Started with Doma-Using Projection with the Criteira API
Getting Started with Doma-Using Subqueries with the Criteria API
Getting Started with Doma-Using Joins with the Criteira API
Getting Started with Doma-Introduction to the Criteria API
Getting Started with DBUnit
Getting Started with Ruby
Getting Started with Swift
Getting Started with Docker
Getting Started with Doma-Transactions
Getting Started with Doma-Dynamicly construct WHERE clauses with the Criteria API
Getting Started with Reactive Streams and the JDK 9 Flow API
Getting Started with GitHub Container Registry instead of Docker Hub
Getting Started with Doma-Annotation Processing
Getting Started with Java Collection
Getting Started with JSP & Servlet
Getting Started with Java Basics
Summarize the words you learned
Getting Started with Spring Boot
Getting Started with Ruby Modules
Generate a serial number with Hibernate (JPA) TableGenerator and store it in the Id of String.
Returning to the beginning, getting started with Java ② Control statements, loop statements
See the behavior of entity update with Spring Boot + Spring Data JPA
Getting Started with Doma-Using Logical Operators such as AND and OR in the WHERE Clause of the Criteria API
Getting Started with Java_Chapter 5_Practice Exercises 5_4
[Google Cloud] Getting Started with Docker
Getting started with Java lambda expressions
Getting Started with Docker with VS Code
Add @ManyToOne as part of the composite primary key in Hibernate JPA
I tried to summarize the key points of gRPC design and development
Don't forget to summarize the features and points of the flea market apps