私はスプリングブート1.4.2を使用します。これは休止状態5.0.11(JPA 2.1)をもたらします。エンティティでJava 8時間クラスを使用したいので、hibernate-Java8
を含めます。
私のエンティティはLocalDateフィールドを定義しています。
@Entity
@Table(name = "my_alarms_timeline", indexes = {...})
public class MyAlarm {
...
@Column(name = "validity_date")
@NotNull
private LocalDate validityDate;
}
これはH2データベースのDATEにマップされると思います。
私のDBでは、これをvalidity_date DATE NOT NULL,
として宣言します。
テストを実行しようとすると、次のエラーが発生します。
[INFO] Caused by: org.hibernate.tool.schema.spi.SchemaManagementException:
Schema-validation: wrong column type encountered in column [validity_date] in table [my_alarms_timeline];
found [date (Types#DATE)], but expecting [timestamp (Types#TIMESTAMP)]
驚いたことに、DB定義をvalidity_date TIMESTAMP NOT NULL,
に変更すると、エラーが発生します
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException:
Schema-validation: wrong column type encountered in column [validity_date] in table [my_alarms_timeline];
found [timestamp (Types#TIMESTAMP)], but expecting [date (Types#DATE)]
これは前のメッセージの逆のメッセージです。
hibernate-Java8
を含める代わりに、AttributeConverter<LocalDate, Java.sql.Date>
を使用することも試みましたが、同じエラー結果が生成されます。
LocalDateがDBのDATEに正しくマップされるようにするには、どうすればよいですか?
LocalDateTime
フィールドをTIMESTAMPにマップして試したところ、問題なく動作しました...
そのため、columnDefinition="DATE"
アノテーションに@Column
を追加して実行しました。
@Entity
@Table(name = "my_alarms_timeline", indexes = {...})
public class MyAlarm {
...
@Column(name = "validity_date", columnDefinition = "DATE")
@NotNull
private LocalDate validityDate;
}
なぜ他の誰もこの問題を見ていません...
私はこれをSpringでは使用していませんが、「標準」JPAでは次のようなことをしています。
@Converter(autoApply = true)
public class OffsetDateTimeAttributeConverter implements AttributeConverter<OffsetDateTime, Timestamp> {
@Override
public Timestamp convertToDatabaseColumn(OffsetDateTime entityValue) {
if( entityValue == null )
return null;
return Timestamp.from(Instant.from(entityValue));
}
@Override
public OffsetDateTime convertToEntityAttribute(Timestamp databaseValue) {
if( databaseValue == null )
return null;
return OffsetDateTime.parse(databaseValue.toInstant().toString());
}
}
テーブルに「タイムスタンプとタイムゾーン」列があります。次に、@ EntityはOffsetDateTimeを使用します。あなたはこのようなものであなたのデータ型の間で変換することができるはずです。
プロジェクトのどこかに次のコードがあると思います。
@EntityScan(basePackageClasses = { Application.class, Jsr310JpaConverters.class })
Hibernate 5.xを使用している場合は、Jsr310JpaConverters.classへの参照を削除する必要があります。そうしないと、HibernateとSpringの両方がJava 8 Date and Timeオブジェクトを処理しようとします。これにより、動作が非常に不安定になる場合があります。 (UTCを使用しないマシンで実行すると、LocalDateインスタンスが誤った値で永続化されるなど)。
また、次のものもすべて削除する必要があります。
@Column(columnDefinition = "DATE")
必要な場合は、休止状態の構成に重大な問題があることを示しています。