如何在使用envers时保存其他属性

时间:2016-12-08 07:58:23

标签: java hibernate-envers

我在修订历史记录中使用了Hibernate Envers。 这是我的表格设置:

CREATE TABLE EPIC (
epicid SERIAL NOT NULL,
accountid BIGINT NOT NULL, 
description TEXT NOT NULL UNIQUE,
epicowner TEXT NOT NULL,
PRIMARY KEY(epicid)
);

CREATE TABLE EPIC_AUD(
epicid BIGINT NOT NULL ,
REV BIGINT NOT NULL,
accountid BIGINT,
description TEXT,
epicowner TEXT,
REVTYPE BIGINT,
PRIMARY KEY(epicid,REV)
);

目前,当我进行更改时,它仅保存复合主键值和修订类型。由于我还想记录删除某个实体的用户,我也想保存该值。这是我用于删除实体的代码。

@Override
public boolean deleteItem(Epic epicFromFrontend) {
    transactionBegin();
    Epic epicToRemove = getEntityManager().find(Epic.class,  epicFromFrontend.getEpicid());
    epicToRemove.setAccountid(epicFromFrontend.getAccountid());
    getEntityManager().remove(epicToRemove);
    return transactionEnd();
}

其实我有两个问题:

  1. 如何保存accountid
  2. 或者保存所有数据可能更聪明,更好。所以删除后我的EPIC_AUD表中没有空字段。

2 个答案:

答案 0 :(得分:1)

通常的做法是在插入,更新或删除域实体期间捕获特定于审核的各种其他信息。

一种简单但具有侵入性的方法是将该状态存储在与实体相同的结构中,如Marcin H所建议的那样。虽然这种方法可行,但这种方法存在一些问题。

  1. 混合问题
    这里的问题是历史相关信息现在与域特定数据一起存储。与安全性非常相似,审计是一个跨领域的问题,因此在数据结构方面应该以同样的方式对待。此外,由于操作模式中的多个审计行,您通常会在多个表中表示相同的用户,时间戳等,从而导致不必要的架构和表膨胀。

  2. 数据删除不必要的字段/操作
    当您将该calibur的字段存储在实体本身时,它会引入一组有趣的需求作为实体删除过程的一部分。如果您希望Envers跟踪该删除用户,那么您必须在删除之前使用该用户执行实体更新,或者引入一个额外的列来跟踪是否软删除行,如Marcin H.所示

  3. 我建议使用我发布的here策略来描述如何利用Envers自定义 RevisionEntity 数据结构,而不是上述内容,允许您跟踪多列数据。与当前的交易操作有关。

    此方法具有以下额外好处:

    1. 没有Envers(审核)特定代码遍布您的DAO方法。您的DAO方法将继续专注于特定于域的操作,因为它应该是。
    2. 在单个事务中操作多个实体的情况下,现在每个事务只捕获一次各种审计属性(每个修订版一次)。这意味着如果用户添加,删除和更新各行,则他们都会被标记一次。
    3. 您现在可以轻松跟踪执行行删除的人员,因为审核属性保留在 RevisionEntity 上,将为删除生成。处理此案例不需要特殊操作或字段。此外,您可以在删除时启用存储实体快照,然后可以访问(1)删除行的行和(2)删除行之前的行。

答案 1 :(得分:0)

您可以将attribue record_active boolean 添加到表格epic,以及表格 epic_aud 当然。 当 record_active false 时,表示记录已被删除"。 永远不要删除任何物理记录 - 事实上它是一种好的做法:)