8

私はHibernateを初めて使用し、Hibernateを使用するWebプロジェクトに取り組んでいます。

java.sql.Timestamp日付object( )属性modifiedDateを持つareaというオブジェクトがあります。新しいオブジェクトを作成すると、modifieDateはnullになり、それgetHibernateTemplate().saveOrUpdate(area);を拡張する独自のクラスに送信した後org.springframework.orm.hibernate3.support.HibernateDaoSupport、現在のタイムスタンプで設定され、データベースに保存されます。データベースでは、として保存されますdatetime

私の問題は、ほとんどの場合、オブジェクトがデータベースに保存されている日付と比較して1ミリ秒ずれた日付で更新されることです。これにより、ページをリロードせずに更新しようとすると、この例外が発生します。

an org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

その後データベースからオブジェクトを取得するときに正しい日付に問題はありません。作成時にのみ、間違った値を取得します。

SaveOrUpdateで正しいmodifiedDateを取得する方法はありますか?

マッピングで使用する必要がある場合、<timestamp name="modifiedDate" column="ModifiedDate"/>すべてのテストはローカルホストで実行され、すべてが同じマシンで実行されます。

getHibernateTemplate().refresh(area);saveOrUpdateの直後に呼び出すことで、正しいタイムスタンプを取得するという回避策がすでにありますが、 saveOrUpdateで正しいmodifiedDateを取得する方法があるかどうかを知りたいです。

4

1 に答える 1

4

私の理論:

何が起こっているのかというと、データベース側ではJava側よりも精度の低いデータ型を使用しているため、DBに保持する値は、DB固有のSQLの生成中に精度を失います(または何らかの方法で丸められます。以下を参照)。 。確実に伝える方法は次のとおりです。

  1. Hibernateは、データベースで実行されるSQLステートメントを生成することによって機能することを忘れないでください。このようなHibernateマッピングの問題を診断するには、何が起こっているのかを正確に知るために、実行されているSQLを確認する必要があります。

  2. Hibernateの「showSQL 」設定をオンにします。これにより、Hibernateはデータベースで実行されている生のSQLをダンプします。

  3. テストのログを調べます。クラスに実装toStringし、値をログに記録して、.に対してhibernateが生成するSQLと比較するのに役立ちますINSERT。SQLステートメントの値はJavaタイムスタンプフィールドの値と一致していますか?

DATETIMEデータベースのタイプの精度設定を確認する必要があります。たとえば、SQL Serverでは、ミリ秒の丸めDATETIME(「精度」フィールドを参照)を実装して、ミリ秒の値の精度を効果的に低下させます。精度のニーズに応じて、列がマップされているJavaタイプを変更するか、データベース内の列のタイプを変更する必要があります。

于 2012-08-18T16:12:10.210 に答える