2016-07-07 11 views
4

Ich habe ein Problem mit JPA Auditing und für @Embedded Mitglieder. Betrachten Sie die folgende Beispielszenario:Auditing und @Embedded im Frühjahr Daten JPA

I eine Testtabelle in einer Oracle-DB eingerichtet:

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

I definieren eine JPA @Entity mit Revisions:

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

} 

Schließlich ermöglichen I JPA Revision in mein :

@SpringBootApplication() 
@EnableJpaAuditing() 
public class AuditTestApplication { 
} 

So weit so gut; Wenn ich eine AuditTest Instanz erstelle, weisen Sie ihr eine ID und ein Commit zu, die Spalte creationDate wird wie erwartet mit dem aktuellen Zeitstempel gefüllt.

jedoch Dinge aufhören zu arbeiten, wenn ich die Prüfung Spalte in einer @Embeddable kapseln:

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

} 

Dann habe ich meine Entitätsklasse ändern das Erstellungsdatum einzubetten:

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

} 

Und leider die Prüfung funktioniert nicht mehr.

Kennt jemand hier eine Möglichkeit, die Auditing-Funktionalität zu speichern, während immer noch @Embedded Klassen verwendet werden?

+1

Die Informationen haben auf einer verwalteten Einheit sein (zumindest das ist, wie es gemacht wird und funktioniert jetzt). Daher gibt es momentan keinen anderen Weg, sie direkt zur Entität hinzuzufügen. –

+0

Hallo, also die einzige verfügbare Option besteht darin, jeder Entität die erforderlichen Felder direkt hinzuzufügen, z. B .: Benutzerersteller, Benutzeraktualisierung, Datumserstellungsdatum, Datum updateDate? Ist es richtig? – Paolo

Antwort

0

Spring Data-Audit-Annotationen in verschachtelten (eingebetteten) Klassen werden noch nicht unterstützt. Hier ist the jira ticket Anforderung dieser Funktion.

Wir könnten jedoch benutzerdefinierte Überwachungslistener verwenden, um Überwachungsinformationen in einbettbaren Klassen festzulegen.

Hier ist die Beispielimplementierung aus einem Blog: How to audit entity modifications using the JPA @EntityListeners, @Embedded, and @Embeddable annotations.

Fähiges Audit

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

Audit Listener

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()); 
    } 
} 

Prüffähige

public interface Auditable { 

    Audit getAudit(); 

    void setAudit(Audit audit); 
} 

Beispiel Entity

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

    @Id 
    private Long id; 

    @Embedded 
    private Audit audit; 

    private String title; 

    } 
Verwandte Themen