当数据库列名称不同时,在基本实体类中定义审计列?

时间:2017-01-18 13:12:08

标签: java hibernate jpa

我在每个表中都有一个包含常见审计列但具有不同列名的数据库。

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

    }
}

3 个答案:

答案 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{
}