Close

JPA - Entity Auditing by using @EntityListeners

[Last Updated: Jan 22, 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