Can I use Spring Data JPA Auditing without the orm.xml file (using JavaConfig instead)?

前端 未结 3 842
感动是毒
感动是毒 2020-12-17 11:18

I\'m trying to get Spring Data Auditing to work in my Spring 3.2.8 / Spring Data 1.5 / Hibernate 4 project.

As per the Spring Data Auditing docs, I\'ve added the

相关标签:
3条回答
  • 2020-12-17 11:32

    Using Stephan's answer, https://stackoverflow.com/a/26240077/715640,

    I got this working using a custom listener.

    @Configurable
    public class TimestampedEntityAuditListener {
    
        @PrePersist
        public void touchForCreate(AbstractTimestampedEntity target) {
            Date now = new Date();
            target.setCreated(now);
            target.setUpdated(now);
        }
    
        @PreUpdate
        public void touchForUpdate(AbstractTimestampedEntity target) {
            target.setUpdated(new Date());
        }
    }
    

    And then referencing it in my base class:

    @MappedSuperclass
    @EntityListeners({TimestampedEntityAuditListener.class})
    public abstract class AbstractTimestampedEntity implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.TABLE)
        private Long id;
    
        @Temporal(TemporalType.TIMESTAMP)
        private Date created;
    
        @Temporal(TemporalType.TIMESTAMP)
        private Date updated;
    
        public Date getCreated() {
            return created;
        }
    
        public void setCreated(Date created) {
            this.created = created;
        }
    
        public Date getUpdated() {
            return updated;
        }
    
        public void setUpdated(Date updated) {
            this.updated = updated;
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    }
    

    FWIW, I'm using this in a spring-boot project, without an orm.xml file.

    0 讨论(0)
  • 2020-12-17 11:35

    Short version: No

    As of JPA 2.0, it is not possible to define such entity listener without an XML file (orm.xml).

    JPA 2.0:

    Default entity listeners—entity listeners that apply to all entities in the persistence unit—can be specified by means of the XML descriptor. (p.93)

    Long version: The workaround...

    If all entities in your project extends an AbstractAuditable superclass then you can put @EntityListeners({AuditingEntityListener.class}) on AbstractAuditable. Listeners attached to an entity class are inherited by its subclasses.

    JPA 2.0:

    Multiple entity classes and mapped superclasses in an inheritance hierarchy may define listener classes and/or lifecycle callback methods directly on the class. (p.93)

    Note that a subclass can exclude explicitly an inherited listener using the @ExcludeSuperclassListeners annotation.

    There is one last interesting footnote from the spec I'd like to quote:

    JPA 2.0:

    Excluded listeners may be reintroduced on an entity class by listing them explicitly in the EntityListeners annotation or XML entity-listeners element. (Footnote [45] p.97)


    Here is some code for illustrating the workaround:

    AbstractAuditableEntity.java

    import java.util.Date;
    
    import javax.persistence.EntityListeners;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.MappedSuperclass;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    import org.springframework.data.annotation.CreatedDate;
    import org.springframework.data.annotation.LastModifiedDate;
    import org.springframework.data.jpa.domain.support.AuditingEntityListener;
    
    @MappedSuperclass
    @EntityListeners({AuditingEntityListener.class}) // AuditingEntityListener will also audit any subclasses of AbstractAuditable...
    public abstract class AbstractAuditableEntity {
        @Id
        @GeneratedValue
        private Long id;
    
        @CreatedDate
        @Temporal(TemporalType.TIMESTAMP)
        private Date createdDate;
    
        @LastModifiedDate
        @Temporal(TemporalType.TIMESTAMP)
        private Date lastModifiedDate;
    }
    

    MyEntity.java

    @Entity
    public abstract class MyEntity extends AbstractAuditableEntity {
    
    }
    

    I think an interface Auditable may be used (@EntityListeners can appear on an interface) instead of an AbstractAuditable class but I didn't try...


    Reference: JSR-000317 Java Persistence 2.0 - Final Release

    0 讨论(0)
  • 2020-12-17 11:42

    In 1.9 of spring data you can enable JPA audits with a couple annotations.

    From the docs - http://docs.spring.io/spring-data/jpa/docs/1.9.4.RELEASE/reference/html/#jpa.auditing

    Using the @EntityListeners(AuditingEntityListener.class) annotation to enable class by class audits. I use it in a base class.

    You'll also need @EnableJpaAuditing on a @Configuration class to enable audits in general.

    0 讨论(0)
提交回复
热议问题