Нужно знать, изменилось ли каждое поле, как мне смоделировать это в Hibernate - PullRequest
3 голосов
/ 02 декабря 2011

Итак, у меня есть класс с тремя полями, который отображается в таблицу с помощью hibernate

Class Widget
{
     String field1;
     String field2;
     String field3;
}

При запуске приложения несколько раз эти виджеты будут добавляться в базу данных из внешних файлов, но при выходе из приложения мне нужно знать, какие (если они есть) из этих полей были изменены пользователем с момента приложения был запущен, поэтому изменения могут быть сохранены обратно в файлы. Мне также нужно сохранить исходное значение для целей ведения журнала.

Я не могу работать, нужно ли мне поле статуса в таблице или уже есть способ сделать это с помощью Hibernate / Database.

РЕДАКТИРОВАТЬ: хорошее решение для программы было дано ниже. однако основная причина, по которой я использую Hibernate, заключается в том, чтобы уменьшить потребление памяти, поэтому сохранение исходных значений при их изменении не является хорошим решением для меня, я хочу, чтобы что-либо сохранялось в базе данных. Итак, я создал новый вопрос Как сохранить копию каждой сущности, которую я добавляю в базу данных в Hibernate

Ответы [ 3 ]

4 голосов
/ 02 декабря 2011

Учитывая объект, подобный следующему, вы можете отслеживать изменения в одном из его полей (сохраняя при этом и его первоначальное значение).

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

  ...

}

Если есть одна строка вбаза данных, подобная этой:

     id: 1
  field: a
version: 2011-12-02 11:24:00

до обновления поля (скажем, от a до b), вы получите следующий вывод.

Original: d, New: b

Исходное значение сохраняется, даже если сущность обновляется несколько раз, и оба состояния могут быть доступны через соответствующие методы получения ( getField и getOriginalField - вы можете стать более креативнымичем я в именовании:).

Таким образом, вы можете сэкономить на создании столбцов версий в своей базе данных, а также скрыть детали реализации от клиентов.

Вместо AtomicReferenceArrayвы можете использовать массивы, списки и т. д. для отслеживания всех изменений подобным образом.

Конечно, @PreUpdate необязательно, но таким образом вы можете получать уведомления об изменениях в состоянии сущности и атомарно сохранятьTон обновил поля в файл.Есть и другие аннотации, подобные этим: см. Документацию для javax.persistence для других типов аннотаций.

0 голосов
/ 02 декабря 2011

Если вам нужно синхронизировать файлы сразу после сохранения в базе данных, вы можете использовать механизм событий Hibernate для перехвата любого сохранения в базу данных и сохранения его в файл, вот пример образца , который делает это.

0 голосов
/ 02 декабря 2011

Если вы используете MySql, то вы можете получить время последнего обновления таблицы из базы данных information_schema, например

SELECT UPDATE_TIME FROM  `information_schema`.`tables` 
          WHERE TABLE_SCHEMA = 'dbName' AND TABLE_NAME = 'tableName'

В противном случае простым решением будет добавить столбец для отметки времени обновления.Этим вы можете даже отслеживать, какая именно строка была обновлена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...