22

Spring 3.1.0.RELEASE、JSF 2.x、JPA2とHibernateProvider、MySql5.1.xを使用してWebアプリケーションを実行しています。アプリケーションはTomcat7.Xで実行されます。

私のエンティティには、最終更新日のような日付があります。

@Column(name = "last_update_date", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdateDate;

今のところ、更新するトリガーがあります。

CREATE TRIGGER upd_site BEFORE UPDATE ON site
FOR EACH ROW SET NEW.last_update_date = CURRENT_TIMESTAMP();

正常に動作しますが、JPAhttp://www.objectdb.com/java/jpa/persistence/eventにいくつかのコールバックメソッドがあることに気付きました

JPAイベントとMySqlのトリガーの間で最も優れているものは何ですか?

ありがとう。

4

2 に答える 2

33

最高のものはありません。データベーストリガーは、行の更新に使用された方法(Hibernate、JDBCクエリ、またはデータベース管理ツールからの更新)に関係なく、行が更新されるたびに最終更新日を更新します。JPAコールバックは、JPAを使用して行が更新された場合にのみ呼び出されます。あなたはどちらかが欲しいかもしれません。

もう1つの違いは、JPAがデータベースによって実行されるトリガーを認識しないことです。したがって、エンティティの一部のフィールドを更新し、JPAが変更をフラッシュした場合、更新日はトリガーによって変更されますが、JPAエンティティは更新日の古い値をメモリに保持します。したがって、この更新日が更新後にGUIに表示される場合、更新日は正しくありません。最新の更新日を取得するには、エンティティを更新する必要があります。

于 2012-06-21T11:09:50.063 に答える
20

DBのトリガーとJPAリスナーの両方で使用しましたが、次の理由でJPAリスナーを決定しました。

  • JPAコードでデータベースと通信する唯一のコードなので、タイムスタンプフィールドが古くなることを心配する必要はありません。(これが将来変更された場合、トリガーを追加して、マップされたスーパーカルを変更できます)

  • JPAリスナーは、データベースに多くのトリガーを作成する必要がなかったという意味でそれほど複雑ではないため、維持するものが少なくなりました。私は積極的にdb構造を開発および変更しているので、開発を迅速に繰り返すときにトリガーを更新する必要がないので、その素晴らしいことに沿って進んでいます。

  • 私はデータベースを完全に制御し、すべてのテーブルに整数のpkeyと整数のバージョンがあり、タイムスタンプ付きのテーブルにはinsert_tsこれらupdate_tsが私のデータベース設計の普遍的なルールであるというルールを作成しました。簡単です。これらの2つのマップされたスーパークラスを使用すると、すべてのエンティティを簡単にコーディングできます。

@MappedSuperclass
public abstract class PersistableObject {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="pkey")
    private Integer pkey;

    @Version
    @Column(name="version")
    private Integer version;

    public Integer getPkey() {
        return this.pkey;
    }

    public Integer getVersion() {
        return this.version;
    }

    @Override
    public String toString() {
        return "Presistable Object: pkey=" + this.pkey + " Object: " + this.getClass().getName();
    }
}

@MappedSuperclass
public class TimeStampedPersistableObject extends PersistableObject {

    @Column(name = "insert_ts")
    @Temporal(TemporalType.TIMESTAMP)
    private Date    insertTimestamp;

    @Column(name = "update_ts")
    @Temporal(TemporalType.TIMESTAMP)
    private Date    updateTimestamp;

    @SuppressWarnings("unused")
    @PrePersist
    private void onInsert() {
        this.insertTimestamp = new Date();
        this.updateTimestamp = this.insertTimestamp;
    }

    @SuppressWarnings("unused")
    @PreUpdate
    private void onUpdate() {
        this.updateTimestamp = new Date();
    }


    public Date getInsertTimestamp() {
        return this.insertTimestamp;
    }


    public Date getUpdateTimestamp() {
        return this.updateTimestamp;
    }
}
于 2012-06-22T13:30:44.533 に答える