Close

JPA - Entity Auditing by using @EntityListeners

[Updated: Jan 22, 2018, Created: Jan 21, 2018]

In last example, we saw how to use @EntityListeners to define entity listeners. In this tutorial, we will see a real scenario where this approach (as compared to using entity as listener) can be beneficial.

Example

The Entities

public interface Auditable {

  Timestamp getDateCreated();

  void setDateCreated(Timestamp dateCreated);

  Timestamp getLastUpdated();

  void setLastUpdated(Timestamp lastUpdated);
}
@Entity
@EntityListeners(AuditableListener.class)
public class Article implements Auditable {
  @Id
  @GeneratedValue
  private int id;
  private String content;
  @ManyToOne(cascade = CascadeType.ALL)
  private Publisher publisher;
  private Timestamp dateCreated;
  private Timestamp lastUpdated;
    .............
}
@Entity
@EntityListeners(AuditableListener.class)
public class Publisher implements Auditable {
  @Id
  @GeneratedValue
  private int id;
  private String name;
  private Timestamp dateCreated;
  private Timestamp lastUpdated;

  public Publisher() {
  }

  public Publisher(String name) {
      this.name = name;
  }
    .............
}

The Listener

public class AuditableListener {
  @PrePersist
  void preCreate(Auditable auditable) {
      Timestamp now = Timestamp.from(Instant.now());
      auditable.setDateCreated(now);
      auditable.setLastUpdated(now);
  }

  @PreUpdate
  void preUpdate(Auditable auditable) {
      Timestamp now = Timestamp.from(Instant.now());
      auditable.setLastUpdated(now);
  }
}

Persisting and Updating Entities

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

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

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

  public static void updateArticle() {
      System.out.println("-- loading and updating Article --");
      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);
      System.out.println("Related Publisher: " + article.getPublisher());
  }

  public static void updatePublisher() {
      System.out.println("-- loading and updating Publisher --");
      EntityManager em = entityManagerFactory.createEntityManager();
      Publisher publisher = em.find(Publisher.class, 2);
      em.getTransaction().begin();
      publisher.setName("Jerry");
      em.getTransaction().commit();
      em.close();
      System.out.println("Publisher updated: " + publisher);
  }

  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();
      for (Article article : resultList) {
          System.out.println(article);
          System.out.println(article.getPublisher());
      }
  }
}
-- persisting --
Article persisted: Article{id=1, content='some test content', dateCreated=2018-01-21 22:29:51.123, lastUpdated=2018-01-21 22:29:51.123}
Related Publisher: Publisher{id=2, name='Adam', dateCreated=2018-01-21 22:29:51.134, lastUpdated=2018-01-21 22:29:51.134}
-- loading and updating Article --
Article updated: Article{id=1, content='new updated content', dateCreated=2018-01-21 22:29:51.123, lastUpdated=2018-01-21 22:29:51.165}
Related Publisher: Publisher{id=2, name='Adam', dateCreated=2018-01-21 22:29:51.134, lastUpdated=2018-01-21 22:29:51.134}
-- loading and updating Publisher --
Publisher updated: Publisher{id=2, name='Jerry', dateCreated=2018-01-21 22:29:51.134, lastUpdated=2018-01-21 22:29:51.169}
-- loading --
Article{id=1, content='new updated content', dateCreated=2018-01-21 22:29:51.123, lastUpdated=2018-01-21 22:29:51.165}
Publisher{id=2, name='Jerry', dateCreated=2018-01-21 22:29:51.134, lastUpdated=2018-01-21 22:29:51.169}

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 with @EntityListeners Example Select All Download
  • jpa-audit-using-entity-listeners
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • Article.java
          • resources
            • META-INF

    See Also