Şuayb's BlogŞuayb's Blog
Home
Categories
Games
MediumAboutContact
Language
Theme
    1. Blog
    2. Programming
    3. Spring Boot JPA Auditing

Spring Boot JPA Auditing

PublishedApril 10, 2025
UpdatedApril 11, 2025
Reading time3 min read
JavaKotlinSpring BootSpring DataJPAAuditing
XLinkedInFacebook
Spring Boot JPA Auditing

Loading likes...

JPA Auditing in Spring Boot allows you to automatically track who created or modified an entity and when. This is extremely useful for audit logs, history tracking, and debugging.


Last updatedApril 11, 2025

Total viewsLoading hits...

Previous articleSpring Boot Test-Driven DevelopmentNext articleSpring Boot AI Integration
Şuayb Şimşek

Written by

Şuayb Şimşek

Backend-focused fullstack developer sharing practical notes on Spring Boot, security, microservices, and cloud-native architecture.

Expertise

  • Spring Boot
  • Go
  • Microservices
  • Next.js
  • Cloud Native

Connect

GitHubLinkedInMedium

Related posts

Spring Boot JWE Authentication with JPA
Programming

Spring Boot JWE Authentication with JPA

Learn how to use stateless encrypted JWTs (JWE) to secure your Spring Boot APIs while persisting user identities and roles in a JPA-backed database.

May 11, 20254 min read
JavaKotlinSpring BootSecurityJWTJWEJPA
Spring Boot Configuration Properties
Programming

Spring Boot Configuration Properties

Learn how to use @ConfigurationProperties for type-safe configuration, validate settings with @Validated, and manage environment-specific values with profile-specific application-{profile}.yml files.

February 4, 20263 min read
JavaKotlinSpring BootConfiguration
Spring Boot GraphQL JWE Authentication
Programming

Spring Boot GraphQL JWE Authentication

Learn how to secure your Spring Boot GraphQL APIs with stateless encrypted JWTs (JWE) while persisting user identities and roles in a JPA-backed database.

May 17, 20256 min read
JavaKotlinSpring BootSecurityJWTJWEGraphQL

About

Articles on Spring Boot, microservices, security, and more.

ContactStart here

Latest posts

  • Captain Tsubasa 2: World Fighters
  • Captain Tsubasa: Rise of New Champions
  • Spring Boot Configuration Properties
  • Spring Boot GraphQL JWE Authentication
  • Spring Boot JWE Authentication with JPA

Top topics

JavaKotlinSpring BootJWEJWTMicroservice

Subscribe

Get practical backend + fullstack notes when new articles are published.

Social

© 2024-2026 Şuayb's Blog. All rights reserved.

🌟 Why Use JPA Auditing?

In this section, we clarify Why Use JPA Auditing? and summarize the key points you will apply in implementation.

  • 📅 Auto track createdDate, lastModifiedDate
  • 👤 Record createdBy, modifiedBy
  • 🧼 Cleaner code by avoiding manual field setting

📋 Prerequisites

Before you start, prepare the following:

  • Java 17+
  • Spring Boot 3.x project with Spring Data JPA
  • A configured datasource (H2, PostgreSQL, MySQL, etc.)
  • Basic familiarity with JPA entities and repository flow

🛠️ Step 1: Add Dependencies

Make sure you have the following dependencies in your project:

Maven:

XMLpom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Gradle:

GROOVYbuild.gradle
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}

🛠️ Step 2: Enable JPA Auditing

Add @EnableJpaAuditing to your main class or a configuration class.


🛠️ Step 3: Create AuditorAware Bean

This bean tells Spring Security who the current user is. Here's a basic static user example:


🛠️ Step 4: Annotate Your Entity

Use auditing annotations like @CreatedDate, @LastModifiedDate, etc.


▶️ Running the Application

Now when you save an entity using JpaRepository, auditing fields will be populated automatically.


🧪 Testing

You can test JPA Auditing functionality by saving an entity and checking whether the audit fields are populated.


🏁 Conclusion

You now have a practical Spring Boot JPA Auditing implementation with a clear, production-friendly Spring Boot structure. As a next step, adapt configuration and tests to your own domain, then validate behavior under realistic traffic and failure scenarios.

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

@SpringBootApplication
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class DemoApplication {
  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
}
KOTLINDemoApplication.kt
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.data.jpa.repository.config.EnableJpaAuditing

@SpringBootApplication
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}
JAVAAuditingConfig.java
@Configuration
public class AuditingConfig {

  @Bean
  public AuditorAware<String> auditorProvider() {
    return () -> Optional.of("Şuayb");
  }
}
KOTLINAuditingConfig.kt
@Configuration
class AuditingConfig {

  @Bean
  fun auditorProvider(): AuditorAware<String> = AuditorAware { Optional.of("Şuayb") }
}
JAVAArticle.java
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Article {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  private String title;

  @CreatedDate
  private LocalDateTime createdDate;

  @LastModifiedDate
  private LocalDateTime lastModifiedDate;

  @CreatedBy
  private String createdBy;

  @LastModifiedBy
  private String lastModifiedBy;

  // getters & setters
}
KOTLINArticle.kt
@Entity
@EntityListeners(AuditingEntityListener::class)
data class Article(
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  val id: Long? = null,

  var title: String? = null,

  @CreatedDate
  var createdDate: LocalDateTime? = null,

  @LastModifiedDate
  var lastModifiedDate: LocalDateTime? = null,

  @CreatedBy
  var createdBy: String? = null,

  @LastModifiedBy
  var lastModifiedBy: String? = null
)
JAVAArticleRepositoryTest.java
@SpringBootTest
@AutoConfigureTestDatabase
@Transactional
class ArticleRepositoryTest {

  @Autowired
  private ArticleRepository articleRepository;

  @Test
  void testAuditFieldsAreSet() {
    Article article = new Article();
    article.setTitle("Test Title");

    Article saved = articleRepository.save(article);

    assertNotNull(saved.getCreatedDate());
    assertNotNull(saved.getLastModifiedDate());
    assertEquals("Şuayb", saved.getCreatedBy());
    assertEquals("Şuayb", saved.getLastModifiedBy());
  }
}
KOTLINArticleRepositoryTest.kt
@SpringBootTest
@AutoConfigureTestDatabase
@Transactional
class ArticleRepositoryTest {

  @Autowired
  lateinit var articleRepository: ArticleRepository

  @Test
  fun `should set audit fields`() {
    val article = Article().apply {
      title = "Test Title"
    }

    val saved = articleRepository.save(article)

    assertNotNull(saved.createdDate)
    assertNotNull(saved.lastModifiedDate)
    assertEquals("Şuayb", saved.createdBy)
    assertEquals("Şuayb", saved.lastModifiedBy)
  }
}