我在每个表中都有一个包含常见审计列但具有不同列名的数据库。
e.g Person表具有以下审计列,
(per_creation_user, per_creation_date, per_update_user, per_update_date), and the address table has audit columns called (add_creation_user, add_creation_date, add_update_user, add_update_date).
我正在尝试使用JPA注释映射这些注释,并使用事件侦听器类在数据库中持久存储这些审计列时自动填充。
我有一个包含这些审核列的基本抽象类,然后我可以用@MappedSuperclass
注释它并将实体监听器注释放在这里。一切都干净整洁,不幸的是,每个被审计实体的列名都不同。我认为唯一的选择是让审计列分别映射到每个实体上吗?
有人可以提出更好的方法吗?
@EntityListeners(BaseDTOEventListener.class)
@MappedSuperclass
public abstract class BaseDTO {
private String creationUser;
private Date creationDate;
}
@Entity
@Table(name="PERSON")
public class Person extends BaseDTO{
}
@Entity
@Table(name="ADDRESS")
public class Address extends BaseDTO{
}
public class BaseDTOEventListener {
@PrePersist
public void onPreInsert(BaseDTO baseDTO){
baseDTO.setCreationUser("TEST");
baseDTO.setCreationDate(new Date());
}
}
答案 0 :(得分:1)
将@Embeddable
与@MappedSuperClass
结合使用:
首先定义BaseDTO
接口:
@EntityListeners(BaseDTOEventListener.class)
@MappedSuperclass
public abstract class BaseDTO {
public abstract getAuditEmbeddable();
public void setCreationDate(Date date){
getAuditEmbeddable().setCreationDate(date);
}
public void setCreationUser(String user){
getAuditEmbeddable().setCreationUser(user);
}
}
然后定义将保存审计字段的embeddable。 用户最常见的列名称。
@Embeddable
public class AuditEmbeddable{
@Column(name = "creationUser")
private String creationUser;
@Column(name = "creationDate")
private Date creationDate;
public String getCreationUser() {
return creationUser;
}
public void setCreationUser(String creationUser) {
this.creationUser = creationUser;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}
然后,您将嵌入到每个审计实体中,并在必要时覆盖列名称:
@Entity
@Table(name="PERSON")
public class Person extends BaseDTO{
@Embedded
private AuditEmbeddable auditEmbeddable;
public AuditEmbeddable getAuditEmbeddable() {
return auditEmbeddable;
}
public void setAuditEmbeddable(AuditEmbeddable auditEmbeddable) {
this.auditEmbeddable = auditEmbeddable;
}
}
@Entity
@Table(name="ADDRESS")
public class Address extends BaseDTO{
// lets say here you have custom names for audit fields
@Embedded
@AttributeOverrides(
@AttributeOverride(name = "creationUser", column = @Column(name = "creationUser123")),
@AttributeOverride(name = "creationDate", column = @Column(name = "creationDate123"))
)
private AuditEmbeddable auditEmbeddable;
public AuditEmbeddable getAuditEmbeddable() {
return auditEmbeddable;
}
public void setAuditEmbeddable(AuditEmbeddable auditEmbeddable) {
this.auditEmbeddable = auditEmbeddable;
}
}
最后,听众可以像你写的一样留下来:
public class BaseDTOEventListener {
@PrePersist
public void onPreInsert(BaseDTO baseDTO){
baseDTO.setCreationUser("TEST");
baseDTO.setCreationDate(new Date());
}
}
希望有所帮助。
答案 1 :(得分:0)
您可以将hibernate envers用于相同的目的。您可以使用@Audited进行注释。将@NotAudited应用于您不想成为的实体
@Entity
@Table(name="PERSON")
@Audited
public class Person extends BaseDTO{
}
@Entity
@Audited
@Table(name="ADDRESS")
public class Address extends BaseDTO{
}
答案 2 :(得分:0)
感谢Alan的提示,通过在每个对象上指定列名如下所示。这工作:)
@Entity
@AttributeOverrides({@AttributeOverride(name="creationUser", column=@Column(name="PER_CREATION_USER", insertable=true, updatable=false)),
@AttributeOverride(name="creationDate", column=@Column(name="PER_CREATION_DATE" insertable=true, updatable=false})
@Table(name="PERSON")
public class Person extends BaseDTO{
}