2017-02-22 8 views
1

Javaベースの休止状態のREST APIからPostgresテーブルにタイムスタンプのDEFAULT値を格納することに関連する1つの問題があります。Postgresのタイムスタンプ列のDEFAULT値設定が正しく使用されない

列は、私達は私達のコードから任意のタイムスタンプ値を送信しない

load_ts timestamp with time zone DEFAULT timezone('utc'::text, now()) NOT NULL, 

として設定されています。 これは、エンティティクラスでタイムスタンプフィールドを指定する方法です。

@Column(name = "LOAD_TS", insertable = false, updatable = false) 
    private Timestamp loadTimeStamp; 

私たちはAmazon RDS Postgres DBを使用しています。 DBパラメータグループ値 'timezone'は 'UTC'に設定されています。

予想されます - DBに送られたload_ts値なしで挿入リクエストがデータベースに送信されると、load_tsはデフォルト設定に基づいてUTCのタイムスタンプを取得する必要があります。

実際 - DBに送られたload_ts値なしで挿入リクエストがデータベースに送信されると、load_tsはEASTERN TIME + 10時間に設定されます。 APIは東部時間に実行されています。

DBにレコードを手動で挿入すると、タイムスタンプが正しく生成されて格納されます。私たちは、RDS postgresのlog_statementsを見ましたが、APIが挿入クエリにタイムスタンプを送信していることを確認していません。また、APIタイムゾーンをUTCに変更すると、タイムスタンプが正しく保存されるという別の興味深い観察がありました。したがって、何とかAPIがタイムゾーンをDBに伝達しています。

アプリケーションスタック - 1)Hibernateのコアバージョン - 5.0.7

2)春 - 4.2

3)のPostgres - 9.4

4)Postgresのドライバ - 9.4.1212.jre7

5)RDS Postgres DBタイムゾーンパラメータグループ値 - UTC

6)米国東部標準時にアプリケーションが実行されている時間帯。

答えて

1

あなたの列の定義は意味をなさない。関数now()は、タイプtimestamp with time zoneを返します。関数timezone()には複数のオーバーロードされたバリアントがありますが、呼び出しを終了するものはtimestamp without time zoneです。そしてそれをタイプtimestamp with time zoneの列に挿入します。

私はここで実際に起こっていることを頭に入れたいとは思っていませんが、米国東部時間とUTCはしばしば5時間離れており、10時間の違いがあるので、おそらくタイムゾーンがありますオフセットは2度適用されます。

あなたの説明から、私はあなたが本当にしたいことは、単に

load_ts timestamp with time zone DEFAULT now() NOT NULL, 

としてあなたの列を定義することで、すべてがうまくされるべきだと思います。

+0

あなたの提案を感謝します。我々は同じ変更を行うことを考えました。私はちょっと混乱しています。なぜなら、この問題は、私が休止状態のアプリケーションを介してデータを挿入しているときにだけ起こっているのです。プレーンSQL挿入ステートメントを使用してデータを挿入するとき、タイムスタンプは正しいです。その場合、timezone()はタイムゾーンとともにタイムスタンプを返します。 –

+0

タイムゾーンなしのタイムスタンプ(関数結果)からタイムゾーン付きタイムスタンプ(カラムタイプ)への変換は、セッションタイムゾーンを考慮しているためです。アプリケーションとpsqlセッションで異なるタイムゾーンが設定されている場合、結果は異なります。 –

+0

ありがとうございましたTon! –

関連する問題