[Java] What is JPA Auditing?

2 minute read

What is JPA Auditing?

When mapping Domain to RDBS table using JPA, there are fields and columns that have Domain in common.

It is typically as follows.

  • CreateDate
  • UpdateDate
    –Identifier

There are fields and columns like this, right?
The fact that it exists for each domain means that the code is duplicated.
This is because it is useful for maintenance to keep a record of who created the database and when.
Therefore, columns like creation date and modification date are really important data.

That’s why JPA offers a feature called Audit. Audit is a function that Spring Data JPA automatically populates the time in the sense of monitoring. When updating after saving the domain in the persistence context or making a query, you have to enter the time data every time, but by using audit, the time is automatically mapped and it is added to the database table. Will put it in.

practice

    1. Create a BaseTimeEntity class in the domain package.
      image.png
  1. Create a BaseTimeEntity as follows.

package jojoidu.boot.springboot.domain;

import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime modifiedDate;
}

The BaseTimeEntity class becomes the parent class of all Entity classes, and ** plays the role of automatically managing createdDate and modifiedDate of Entity class. ** **

  • @MappedSuperclass
    –When JPA Entity class inherits BaseTimeEntity Make sure that fields (createdDate, modifiedDate) are also recognized as columns.

  • @EntityListeners(AuditingEntityListener.class)
    –Give the Auditing function to the BaseTimeEntity class.

  • @CreatedDate
    –The time is automatically saved when the Entity is created and saved.

  • @LastModifiedDate
    –Time is automatically saved when you change the value of the queried Entity.

    1. Inherit BaseTimeEntity class to Entity class.

package jojoidu.boot.springboot.domain.posts;

import jojoidu.boot.springboot.domain.BaseTimeEntity;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Getter
@NoArgsConstructor
@Entity //Indicates the class linked to the table
public class Posts extends BaseTimeEntity {

    @Id //Indicates PK field
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(length = 500, nullable = false)
    private String title;

    @Column(columnDefinition = "TEXT", nullable = false)
    private String content;

    private String author;

    @Builder
    public Posts(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }

    public void update(String title, String content) {
        this.title = title;
        this.content = content;
    }
}


Four. Finally, add the activation annotation to the main class so that the JPA Auditing annotation is activated.


package jojoidu.boot.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@EnableJpaAuditing
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

test

Testing is essential, so I also added a test method.


@Test
    public void saveBaseTimeEntity() {
        // given
        LocalDateTime now = LocalDateTime.of(2020, 8,12,0,0,0);
        postsRepository.save(Posts.builder()
        .title("title")
        .content("content")
        .author("author")
        .build());

        // when
        List<Posts> postsList = postsRepository.findAll();

        //then
        Posts posts = postsList.get(0);

        System.out.println(">>>>>>>createdDate=" + posts.getCreatedDate() + ", modifiedDate=" + posts.getModifiedDate());

        assertThat(posts.getCreatedDate()).isAfter(now);
        assertThat(posts.getModifiedDate()).isAfter(now);
    }

result

image.png
I was able to confirm that it works normally.
I’m too happy to have such fun.