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

问题描述 投票:1回答:3

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

例如,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());

    }
}
java hibernate jpa
3个回答
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());

            }
        }

希望有所帮助。


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

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{
}
© www.soinside.com 2019 - 2024. All rights reserved.