2011-11-20 18 views
14

エンティティオブジェクトの作成日/永続化時に自動的に作成され、「今すぐ」に設定され、再び更新されないDate/DateTime/Timestampフィールドをエンティティオブジェクトに追加したいとします。Play!で自動生成された日付/タイムスタンプフィールドを作成する方法/ JPA?

その他のユースケースには、エンティティの最終変更日を含むように常に更新されたフィールドが含まれていました。

私はそのような要件を達成するために使用しましたin the mysql schema

Playでこれを行うには、どのような方法が最適ですか。/JPA?

+0

データベースは「現在の」日付の値を設定する必要がありますか、またはJPAはそれを行うことができますか? –

+0

@PiotrNowicki - JPAで行うことができます。現在私はアプリケーションコードの中でそれをやっています。 – ripper234

答えて

32

あなたが望むものを達成するために適応できるコードスニペットがあります。見てください:

// 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(); 
    } 
} 
+0

これは、うまくいきました。上記のほかに、@Column(name = "created_date"、updatable = false)という列プロパティを入れないと、更新中に がnullになります。 – Buminda

20

少なくとも2つの方法で達成できると思います。

データベースのデフォルト値

私は最も簡単な方法は、updateable=false, insertable=falseとして列をマークすることだと思う(これはあなたの不変性を与えるだろう - JPAはINSERTUPDATE文にこの列は含まれません)とデータベースの設定列のデフォルト値はNOWです。

JPAライフサイクルコールバックメソッド

他の方法は、実際の日付new Date()にあなたの日付オブジェクトを設定します@PrePersistライフサイクルコールバックメソッドを提供することです。次に、誰もこの値を編集しないようにする必要があります。したがって、このプロパティの設定を行うべきではありません。

エンティティが変更されたときに日付を更新する場合は、同様に実際の変更日を設定するライフサイクルコールバックメソッド​​を実装できます。

ちょうど(あなたがnew Date(oldDate.getTime());代わりの平野return oldDateのようなものを返す必要があります)あなたはDateオブジェクトで作業している場合は、あなたのDateオブジェクトの防衛的コピーを行う必要があることを覚えておいてください。
これは、ユーザーがあなたの日付のゲッターを使用してその状態を変更するのを防ぎます。

+0

更新可能な列= falseなどをどこにマークしますか?アノテーションを使用していますか? ゲッターで防御的なコピーが必要なのはなぜですか? Gettersはとにかく 'save()'を呼び出さないので、どのように値を変更できますか? – ripper234

+0

はい、あなたの日付フィールドに '@ Column'アノテーションを追加します(または' orm.xml'ファイルを使用する場合はその中で行います)。 'java.util.Date'は可変クラスです。ユーザーはgetterを使用して取得できますので、クラスのDateフィールドへの参照を取得します。彼はすなわちdate.setTime(1)を呼び出して、日付の状態を変更することができます。その後、JPAは、ユーザーによって変更された日付オブジェクトを保持します。 –

+0

明示的に 'save()'を呼び出すと、JPAは持続します。とにかく、 "ユーザー"が "自分のプロジェクトにJavaコードを書くことができる人"を意味するのであれば、それは私にとっては問題ではありません。あなたが私のサイトへの実際の訪問者を意味した場合、私は彼らが日付オブジェクト上で 'set'を呼び出すために何をすることができるかを知りません。 – ripper234

関連する問題