需要知道每个字段是否已更改,我应该如何在 Hibernate 中对此进行建模

Pau*_*lor 4 java hibernate

所以我有一个包含三个字段的类,它们使用 hibernate 映射到一个表

Class Widget
{
     String field1;
     String field2;
     String field3;
}
Run Code Online (Sandbox Code Playgroud)

在应用程序启动时,这些小部件将从外部文件添加到数据库中的许多实例,但是当我退出应用程序时,我需要知道自应用程序启动以来用户更改了这些字段中的哪些(如果有),因此可以将更改保存回文件。我还需要存储原始值以用于日志记录。

无论是否需要表中的状态字段,或者是否已经有使用 Hibernate/Database 的方法,我都无法工作。

编辑:下面给出了该程序的一个很好的解决方案。然而,我使用 Hibernate 的主要原因是为了减少内存消耗,因此在更改时存储原始值对我来说不是一个好的解决方案,我希望将所有内容存储在数据库中。所以我创建了这个新问题How do I store a copy of each entity I add to database in Hibernate

Koh*_*ert 5

给定如下所示的实体,您可以跟踪其中一个字段的更改(同时也保留其原始值)。

@Entity
@Table(schema = "test", name = "test")
public final class Test {

  private static final int ORIGINAL = 0;
  private static final int CURRENT = 1;

  private Integer id;

  // holds the original and current state of the field
  private final AtomicReferenceArray<String> field = new AtomicReferenceArray<>(2);

  @Id
  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  @Transient
  public String getOriginalField() {
    return field.get(ORIGINAL);
  }

  @Basic
  public String getField() {
    return field.get(CURRENT);
  }

  public void setField(String field) {
    this.field.compareAndSet(ORIGINAL, null, field);
    this.field.set(CURRENT, field);
  }

  @PreUpdate
  public void preUpdate() {
    System.out.format("Original: %s, New: %s\n", getOriginalField(), getField());
  }

  ...
Run Code Online (Sandbox Code Playgroud)

}

如果数据库中有这样一行:

     id: 1
  field: a
version: 2011-12-02 11:24:00
Run Code Online (Sandbox Code Playgroud)

在该字段更新之前(例如 from ato b),您将获得以下输出。

Original: d, New: b
Run Code Online (Sandbox Code Playgroud)

即使实体被多次更新,原始值也会被保留,并且可以通过相应的 getter 访问这两个状态(getFieldgetOriginalField - 在命名方面,您可以比我更有创意:)。

这样,您就可以不用在数据库中创建版本列,还可以对客户端隐藏实现细节。

相反的AtomicReferenceArray,你可以使用数组,列表等,以跟踪像这样所有的变化。

@PreUpdate当然不是必需的,但通过这种方式,您可以收到实体状态更改的通知,并将更新的字段自动保存到文件中。还有更多这样的注释:请参阅javax.persistence的文档以了解其他注释类型。