在Spring Data JPA中进行审计和@Embedded

jpv*_*vee 7 spring jpa spring-data-jpa

我遇到了JPA审核和@Embedded会员的问题.请考虑以下示例场景:

我在Oracle DB中设置了一个测试表:

CREATE TABLE AUDIT_TEST (
  ID            NUMBER(38)   NOT NULL PRIMARY KEY,
  CREATION_DATE TIMESTAMP(6) DEFAULT SYSTIMESTAMP NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

@Entity用审计定义了一个JPA :

@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;
  }

}
Run Code Online (Sandbox Code Playgroud)

最后,我在我的启用JPA审计@Configuration:

@SpringBootApplication()
@EnableJpaAuditing()
public class AuditTestApplication {
}
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好; 当我构造一个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;
  }

}
Run Code Online (Sandbox Code Playgroud)

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

@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;
  }

}
Run Code Online (Sandbox Code Playgroud)

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

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

The*_*ect 9

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

尚不支持嵌套(可嵌入)类中的 Spring Data 审计注释。这是请求此功能的 jira 票证

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

以下是来自博客的示例实现:如何使用 JPA @EntityListeners、@Embedded 和 @Embeddable 注释审计实体修改

嵌入式审计

@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
}
Run Code Online (Sandbox Code Playgroud)

审计监听器

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

可审计

public interface Auditable {

    Audit getAudit();

    void setAudit(Audit audit);
}
Run Code Online (Sandbox Code Playgroud)

样本实体

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

    @Id
    private Long id;

    @Embedded
    private Audit audit;

    private String title;

  }
Run Code Online (Sandbox Code Playgroud)