JPA Fundamentals & Hibernate - 12) JPQL and Queries
In this article, we will learn what is the JPQL(The Java Persistence Query Language) and how to use it. What is the JPQL The Java Persistence query …
In this article, we are going to learn lifecycle events in the JPA. As of the most application we will have date_created
and last_modified
column to our tables and we will update them via entity lifecycle listeners.
Before everything, let’s create the table first:
CREATE TABLE product
(
id SERIAL PRIMARY KEY,
date_created TIMESTAMP,
last_modified TIMESTAMP,
name VARCHAR(100)
);
If you read my previous articles, this step will be easy for you:
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "date_created")
private LocalDateTime dateCreated;
@Column(name = "last_modified")
private LocalDateTime lastModified;
private String name;
// getters and setters
}
When working with JPA, there are several events that can be notified of during an entity’s lifecycle:
@PrePersist
@PostPersist
@PreRemove
@PostRemove
@PreUpdate
@PostUpdate
@PostLoad
We have two options to use lifecycle event annotations:
Let’s use the event operations in the entity:
public class Product {
// ...
public void setLastModified(LocalDateTime lastModified) {
this.lastModified = lastModified;
}
@PrePersist
public void prePersist() {
System.out.println("Pre persist event called");
this.dateCreated = LocalDateTime.now();
this.lastModified = LocalDateTime.now();
}
@PreUpdate
public void preUpdate() {
System.out.println("Pre update event called");
this.lastModified = LocalDateTime.now();
}
@PostLoad
public void postLoad() {
System.out.println("Post load event called");
System.out.println("Entity: " + this + " was loaded");
}
@PreRemove
public void preRemove() {
System.out.println("PreRemove event called");
System.out.println("Entity: " + this + " will be removed");
}
@PostRemove
public void postRemove() {
System.out.println("PostRemove event called");
System.out.println("Entity: " + this + " was removed");
}
// ...
}
Right now let’s persist a product entity:
public class Main {
public static void main(String[] args) {
try {
entityManager.getTransaction().begin();
Product product1 = new Product();
product1.setName("product1");
entityManager.persist(product1);
entityManager.getTransaction().commit();
}catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
} finally {
entityManager.close();
}
}
}
After run the main method, look at the console:
Pre persist event called
Hibernate:
insert
into
product
(date_created, last_modified, name)
values
(?, ?, ?)
and also table:
select * from product;
id | date_created | last_modified | name
----+----------------------------+----------------------------+----------
1 | 2021-08-12 12:32:36.414129 | 2021-08-12 12:32:36.414166 | product1
If we want to also see the how PreUpdate
works:
public class Main {
public static void main(String[] args) {
try {
entityManager.getTransaction().begin();
Product product1 = entityManager.find(Product.class, 1L);
product1.setName("product1_v2");
entityManager.getTransaction().commit();
}catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
} finally {
entityManager.close();
}
}
}
Console output:
Hibernate:
select
...
Post load event called
Entity: Product{id=1, dateCreated=2021-08-12T12:32:36.414129, lastModified=2021-08-12T12:32:36.414166, name='product1'} was loaded
Pre update event called
Hibernate:
update
...
Process finished with exit code 0
and also table
select * from product;
id | date_created | last_modified | name
----+----------------------------+----------------------------+-------------
1 | 2021-08-12 12:32:36.414129 | 2021-08-12 12:52:12.042188 | product1_v2
Update the main class:
public class Main {
public static void main(String[] args) {
try {
entityManager.getTransaction().begin();
Product product1 = entityManager.find(Product.class, 1L);
entityManager.remove(product1);
entityManager.getTransaction().commit();
}catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
} finally {
entityManager.close();
}
}
}
Console output:
Hibernate:
select
...
---------------- First load the Product ----------------
Post load event called
Entity: Product{id=1, dateCreated=2021-08-12T12:32:36.414129, lastModified=2021-08-12T12:52:12.042188, name='product1_v2'} was loaded
---------------- PreRemove (indicates Product entity will be removed) ----------------
PreRemove event called
Entity: Product{id=1, dateCreated=2021-08-12T12:32:36.414129, lastModified=2021-08-12T12:52:12.042188, name='product1_v2'} will be removed
Hibernate:
delete
...
---------------- PostRemove (indicates Product removed from the context and db) ----------------
PostRemove event called
Entity: Product{id=1, dateCreated=2021-08-12T12:32:36.414129, lastModified=2021-08-12T12:52:12.042188, name='product1_v2'} was removed
Process finished with exit code 0
We can abstract all the date operation into the one class called GeneralEntity
@MappedSuperclass
public abstract class GeneralEntity {
@Column(name = "date_created")
protected LocalDateTime dateCreated;
@Column(name = "last_modified")
protected LocalDateTime lastModified;
// getters and setters
@PrePersist
public void prePersist() {
System.out.println("Pre persist event called");
this.dateCreated = LocalDateTime.now();
this.lastModified = LocalDateTime.now();
}
@PreUpdate
public void preUpdate() {
System.out.println("Pre update event called");
this.lastModified = LocalDateTime.now();
}
}
Update the product entity:
@Entity
@Table(name = "product")
public class Product extends GeneralEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
// getters and setters
@PostLoad
public void postLoad() {
System.out.println("Post load event called");
System.out.println("Entity: " + this + " was loaded");
}
@PreRemove
public void preRemove() {
System.out.println("PreRemove event called");
System.out.println("Entity: " + this + " will be removed");
}
@PostRemove
public void postRemove() {
System.out.println("PostRemove event called");
System.out.println("Entity: " + this + " was removed");
}
}
Just try to insert another product and look at the table:
select * from product;
id | date_created | last_modified | name
----+----------------------------+----------------------------+----------
3 | 2021-08-12 13:08:04.639482 | 2021-08-12 13:08:04.639522 | product2
That’s the final article for the mini JPA series.
In this article, we will learn what is the JPQL(The Java Persistence Query Language) and how to use it. What is the JPQL The Java Persistence query …
In this article, we are going to discuss what is the entity manager in the JPA and also learn the basic operations in the entity manager How to Obtain …