代码之家  ›  专栏  ›  技术社区  ›  jonesy

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

  •  2
  • jonesy  · 技术社区  · 8 年前

    我有一个数据库,每个表中都有公共审计列,但列名不同。

    例如 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 回复  |  直到 8 年前
        1
  •  1
  •   jonesy    8 年前

    感谢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{
    }
    
        2
  •  1
  •   Maciej Kowalski    7 年前

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

    希望这有帮助。

        3
  •  0
  •   Saket Puranik    8 年前

    您可以使用hibernate envers实现相同的目的。您可以使用@Audited进行注释。将@NotAudited应用于您不想成为的实体

    @Entity
    @Table(name="PERSON")
    @Audited
    public class Person extends BaseDTO{
    }
    
    @Entity
    @Audited
    @Table(name="ADDRESS")
    public class Address extends BaseDTO{
    }