Как создать автоматически генерируемое поле Date/timestamp в Play!/JPA?

Я хотел бы добавить поле Date/DateTime/Timestamp в объект сущности, который будет автоматически создан, когда объект будет создан/сохранен и настроен на "сейчас", никогда не обновляться снова.

Другие варианты использования включали поля, которые всегда обновлялись, чтобы содержать дату последнего изменения объекта.

Я использовал для достижения таких требований в схеме mysql.

Какой лучший способ сделать это в Play!/JPA?

Ответы

Ответ 1

Существует фрагмент кода, который вы можете адаптировать для достижения желаемого. Посмотрите:

// Timestampable.java

package models;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Version;

import play.db.ebean.Model;

@MappedSuperclass
public class Timestampable extends Model {

  @Id
  @GeneratedValue
  public Long id;

  @Column(name = "created_at")
  public Date createdAt;

  @Column(name = "updated_at")
  public Date updatedAt;

  @Version
  public int version;

  @Override
  public void save() {
    createdAt();
    super.save();
  }

  @Override
  public void update() {
    updatedAt();
    super.update();
  }

  @PrePersist
  void createdAt() {
    this.createdAt = this.updatedAt = new Date();
  }

  @PreUpdate
  void updatedAt() {
    this.updatedAt = new Date();
  }
}

Ответ 2

Я думаю, вы можете добиться этого, по крайней мере, двумя способами.

Значение по умолчанию для базы данных

Я думаю, что самым простым способом было бы отметить столбец как updateable=false, insertable=false (это даст вам неизменность - JPA не включит этот столбец в выражения INSERT и UPDATE) и установит, что столбец базы данных имеет значение по умолчанию NOW.

Методы обратного вызова JPA Lifecycle

Другим способом было бы обеспечить метод обратного вызова жизненного цикла @PrePersist, который установил бы ваш объект даты на фактическую дату new Date(). Тогда вам нужно будет убедиться, что никто не отредактирует это значение, поэтому вы не должны предоставлять никаких настроек для этого свойства.

Если вы хотите, чтобы дата была обновлена, когда сущность была изменена, вы могли бы аналогичным образом реализовать метод обратного вызова @PreUpdate lifecycle, который установил фактическую дату изменения.

Просто помните, что если вы работаете с объектами Date, вы должны сделать защитную копию вашего объекта Date (так что вы должны вернуть что-то вроде new Date(oldDate.getTime()); вместо plain return oldDate). < ш > Это не позволит пользователям использовать getter вашей даты и изменить его состояние.