Spring Data JPA 中的审计和@Embedded

Auditing and @Embedded in Spring Data JPA

我在 JPA 审计和 @Embedded 成员方面遇到问题。考虑以下示例场景:

我在 Oracle 数据库中设置了一个测试 table:

CREATE TABLE AUDIT_TEST (
  ID            NUMBER(38)   NOT NULL PRIMARY KEY,
  CREATION_DATE TIMESTAMP(6) DEFAULT SYSTIMESTAMP NOT NULL
);

我定义了一个带审计的 JPA @Entity

@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "AUDIT_TEST")
public class AuditTest {

  private Long id;
  private LocalDateTime creationDate;

  @Id
  @Column(name = "ID")
  public Long getId() { return id; }

  public void setId(Long id) { this.id = id; }

  @CreatedDate
  @Column(name = "CREATION_DATE")
  public LocalDateTime getCreationDate() { return creationDate; }

  public void setCreationDate(LocalDateTime creationDate) {
    this.creationDate = creationDate;
  }

}

最后,我在 @Configuration:

中启用了 JPA 审计
@SpringBootApplication()
@EnableJpaAuditing()
public class AuditTestApplication {
}

到目前为止一切顺利;当我构造一个 AuditTest 实例,为其分配一个 id 并提交时,creationDate 列会按预期填充当前时间戳。

但是,当我将审计列封装在 @Embeddable:

中时,一切都停止了
@Embeddable
public class AuditTestEmbeddable {

  private LocalDateTime creationDate;

  @CreatedDate
  @Column(name = "CREATION_DATE")
  public LocalDateTime getCreationDate() { return creationDate; }

  public void setCreationDate(LocalDateTime creationDate) {
    this.creationDate = creationDate;
  }

}

然后我更改实体 class 以嵌入创建日期:

@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "AUDIT_TEST")
public class AuditTest {

  private Long id;
  private AuditTestEmbeddable auditTestEmbeddable = new AuditTestEmbeddable();

  @Id
  @Column(name = "ID")
  public Long getId() { return id; }

  public void setId(Long id) { this.id = id; }

  @Embedded
  public AuditTestEmbeddable getAuditTestEmbeddable() {
    return auditTestEmbeddable;
  }

  public void setAuditTestEmbeddable(AuditTestEmbeddable auditTestEmbeddable) {
    this.auditTestEmbeddable = auditTestEmbeddable;
  }

}

不幸的是,审计不再有效。

这里有人知道在仍然使用 @Embedded classes 的同时保存审计功能的方法吗?

更新: 此功能已添加到 Spring Data 2.1 M2 (Lovelace)。 https://jira.spring.io/browse/DATACMNS-1274

Spring 尚不支持嵌套(可嵌入)类 中的数据审核注释。 the jira ticket 请求此功能。

但是,我们可以使用自定义审计侦听器来设置可嵌入的审计信息类。

这是从博客中获取的示例实现:How to audit entity modifications using the JPA @EntityListeners, @Embedded, and @Embeddable annotations

可嵌入审计

@Embeddable
public class Audit {

    @Column(name = "created_on")
    private LocalDateTime createdOn;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "updated_on")
    private LocalDateTime updatedOn;

    @Column(name = "updated_by")
    private String updatedBy;

    //Getters and setters omitted for brevity
}

审计侦听器

public class AuditListener {

    @PrePersist
    public void setCreatedOn(Auditable auditable) {
        Audit audit = auditable.getAudit();

        if(audit == null) {
            audit = new Audit();
            auditable.setAudit(audit);
        }

        audit.setCreatedOn(LocalDateTime.now());
        audit.setCreatedBy(LoggedUser.get());
    }

    @PreUpdate
    public void setUpdadtedOn(Auditable auditable) {
        Audit audit = auditable.getAudit();

        audit.setUpdatedOn(LocalDateTime.now());
        audit.setUpdatedBy(LoggedUser.get());
    }
}

可审计

public interface Auditable {

    Audit getAudit();

    void setAudit(Audit audit);
}

示例实体

@Entity
@EntityListeners(AuditListener.class)
public class Post implements Auditable {

    @Id
    private Long id;

    @Embedded
    private Audit audit;

    private String title;

  }

使用 spring-data 2.4.4,AuditListener 可以很好地处理嵌入式对象,请参阅 documentation spring-data

spring-data 的最小版本捆绑在 spring-boot 版本 2.4.3