Spring Data Jpa Auditing

Records in Database are created and updated frequently, and some times it required to audit and keep records of insertion and updation. To do so, entity class needs to have auditing metadata such as Created By, Created Date, Last Modified By, Last Modified Date ect. In order to ease the process, Spring data provides us @CreatedBy, @CreatedDate, @LastModifiedBy, @LastModifiedDate annotations respectively.

drop database if exists AppleDb;
create database AppleDb;
use AppleDb;
create table apple (apple_id bigint not null, apple_name varchar(255), taste varchar(255), created_by varchar(255), created_date datetime(6), last_modified_by varchar(255), last_modified_date datetime(6), primary key (apple_id)) engine=InnoDB;
create table hibernate_sequence (next_val bigint) engine=InnoDB;
insert into hibernate_sequence values ( 1 );
package com.sujan.example.jpa.controller;

import com.sujan.example.jpa.entity.Apple;
import com.sujan.example.jpa.repository.AppleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.time.Instant;

@RestController
public class AppleController {
    @Autowired
    private AppleRepository appleRepository;

    @GetMapping
    Apple created() {
        Apple apple = new Apple();
        apple.setAppleName("Macintosh");
        apple.setTaste("sharp");
        apple.setCreatedBy("Apple User");
        apple.setCreatedDate(Instant.now());
        Apple save = appleRepository.save(apple);
        return save;
    }

    @PostMapping
    Apple modified(@RequestBody Apple apple) {
        apple.setTaste("sweet");
        apple.setLastModifiedBy("Apple User");
        apple.setLastModifiedDate(Instant.now());
        Apple save = appleRepository.save(apple);
        return save;
    }
}
package com.sujan.example.jpa.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.time.Instant;

@Data
@Entity
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Apple {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long appleId;
    private String appleName;
    private String taste;
    @CreatedBy
    private String createdBy;
    @CreatedDate
    private Instant createdDate;
    @LastModifiedBy
    private String lastModifiedBy;
    @LastModifiedDate
    private Instant lastModifiedDate;
}

package com.sujan.example.jpa.repository;

import com.sujan.example.jpa.entity.Apple;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface AppleRepository extends CrudRepository<Apple, Long> {
}
package com.sujan.example.jpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JpaApplication {
    public static void main(String[] args) {
        SpringApplication.run(JpaApplication.class, args);
    }
}
spring.datasource.url=jdbc:mysql://localhost:3306/AppleDb?autoReconnect=true&useSSL=false&createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.show-sql=true
spring.datasource.initialization-mode=always
plugins {
    id 'org.springframework.boot' version '2.3.3.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
}
group = 'com.sujan'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
repositories {
    mavenCentral()
}
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    annotationProcessor 'org.projectlombok:lombok'
    compileOnly 'org.projectlombok:lombok'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    runtimeOnly 'mysql:mysql-connector-java'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}
test {
    useJUnitPlatform()
}
curl --location --request GET 'http://localhost:8080/'
select next_val as id_val from hibernate_sequence for update
update hibernate_sequence set next_val= ? where next_val=?
insert into apple (apple_name, created_by, created_date, last_modified_by, last_modified_date, taste, apple_id) values (?, ?, ?, ?, ?, ?, ?)
curl --location --request POST 'http://localhost:8080/' --header 'Content-Type: application/json' --data-raw '{
    "appleId": 1,
    "appleName": "Macintosh",
    "taste": "sharp",
    "createdBy": "Apple User",
    "createdDate": "2021-03-16T05:57:43.073089569Z"
}'
select apple0_.apple_id as apple_id1_0_0_, apple0_.apple_name as apple_na2_0_0_, apple0_.created_by as created_3_0_0_, apple0_.created_date as created_4_0_0_, apple0_.last_modified_by as last_mod5_0_0_, apple0_.last_modified_date as last_mod6_0_0_, apple0_.taste as taste7_0_0_ from apple apple0_ where apple0_.apple_id=?
update apple set apple_name=?, created_by=?, created_date=?, last_modified_by=?, last_modified_date=?, taste=? where apple_id=?

follow us on