Close

JPA - Basic Auditing by using Entity Callback Listeners

[Last Updated: Jan 10, 2018]

In last example, we saw what are callback listeners and how to use them. In this tutorial we will see a real use case example. While making use of listener notifications, we should keep following JSR 338 restriction in mind:

In general, the lifecycle method of a portable application should not invoke EntityManager or query operations, access other entity instances, or modify relationships within the same persistence context. A lifecycle callback method may modify the non-relationship state of the entity on which it is invoked.

Following example shows how to do basic auditing of persisting 'date created' and 'date modified' by using entity lifecycle callback events.

Example

The Entity

@Entity
public class Article {
  @Id
  @GeneratedValue
  private int id;
  private String content;
  private Timestamp dateCreated;
  private Timestamp lastUpdated;

  @PrePersist
  void preCreate() {
      dateCreated = Timestamp.from(Instant.now());
      lastUpdated = Timestamp.from(Instant.now());
  }

  @PreUpdate
  void preUpdate() {
      lastUpdated = Timestamp.from(Instant.now());
  }
    .............
}

Persisting and Updating Entity

public class ExampleMain {
  private static EntityManagerFactory entityManagerFactory =
          Persistence.createEntityManagerFactory("example-unit");

  public static void main(String[] args) {
      try {
          persistArticle();
          updateArticle();
          loadArticles();
      } finally {
          entityManagerFactory.close();
      }
  }

  public static void persistArticle() {
      System.out.println("-- persisting --");
      Article article = new Article();
      article.setContent("some test content");
      EntityManager em = entityManagerFactory.createEntityManager();
      em.getTransaction().begin();
      em.persist(article);
      em.getTransaction().commit();
      em.close();
      System.out.println("Article persisted: " + article);
  }

  public static void updateArticle() {
      System.out.println("-- loading and updating --");
      EntityManager em = entityManagerFactory.createEntityManager();
      Article article = em.find(Article.class, 1);
      em.getTransaction().begin();
      article.setContent("new updated content");
      em.getTransaction().commit();
      em.close();
      System.out.println("Article updated: " + article);
  }

  private static void loadArticles() {
      System.out.println("-- loading --");
      EntityManager em = entityManagerFactory.createEntityManager();
      Query query = em.createQuery("SELECT t FROM Article t");
      List<Article> resultList = query.getResultList();
      resultList.forEach(System.out::println);
  }
}
-- persisting --
Article persisted: Article{id=1, content='some test content', dateCreated=2018-01-10 12:51:31.985, lastUpdated=2018-01-10 12:51:31.985}
-- loading and updating --
Article updated: Article{id=1, content='new updated content', dateCreated=2018-01-10 12:51:31.985, lastUpdated=2018-01-10 12:51:32.021}
-- loading --
Article{id=1, content='new updated content', dateCreated=2018-01-10 12:51:31.985, lastUpdated=2018-01-10 12:51:32.021}

Example Project

Dependencies and Technologies Used:

  • h2 1.4.196: H2 Database Engine.
  • hibernate-core 5.2.12.Final: The core O/RM functionality as provided by Hibernate.
    Implements javax.persistence:javax.persistence-api version 2.1
  • JDK 1.8
  • Maven 3.3.9

Entity Auditing Example Select All Download
  • jpa-audit-using-entity-callback
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • Article.java
          • resources
            • META-INF

    See Also