Как создать автоматически сгенерированное поле даты / времени в Play!/ JPA? - PullRequest
15 голосов
/ 20 ноября 2011

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

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

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

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

Ответы [ 2 ]

35 голосов
/ 21 ноября 2011

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

// 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();
  }
}
21 голосов
/ 20 ноября 2011

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

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

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

Методы обратного вызова жизненного цикла JPA

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

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

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

...