2016-07-07 3 views
4

У меня возникла проблема с аудитом JPA и для @Embedded пользователей. Рассмотрим следующий пример сценария:Аудит и @ Уложенные весной данные JPA

я создать тестовую таблицу в качестве БД Oracle:

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

} 

Наконец, я включаю JPA аудита в мой @Configuration:

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

Пока все хорошо; когда я создаю экземпляр AuditTest, назначьте его id и commit, столбец 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; 
    } 

} 

Тогда я изменить мой класс сущностей вставлять дату создания:

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

+1

Информация должна быть на управляемый объект (по крайней мере, как это делается и сейчас работает). Поэтому в настоящее время нет другого способа добавить его непосредственно к сущности. –

+0

Привет, поэтому единственная доступная опция заключается в том, чтобы добавлять к каждому сущности необходимые поля, такие как: создатель пользователя, пользовательский модуль обновления, дата создания даты, дата updateDate; Правильно ли это? – Paolo

ответ

0

Аутентификация аудита Spring Data во вложенных (встраиваемых) классах пока не поддерживается. Вот 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

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

    @Id 
    private Long id; 

    @Embedded 
    private Audit audit; 

    private String title; 

    } 
Смежные вопросы