私はEclipseLink 2.4.2を使用しています。
外部ライブラリの最終クラスである Money 型の属性を持つ @Entity があります。Money のインスタンスは不変であり、金額用と通貨用の 2 つの列として永続化する必要があります。
これを行うために @ReadTransformer と 2 つの @WriteTransformers を使用しています。
@Transformation(fetch = FetchType.EAGER, optional = false)
@ReadTransformer(transformerClass = MoneyReadTransformer.class)
@WriteTransformers({
@WriteTransformer(
transformerClass = MoneyCurrencyWriteTransformer.class,
column = @Column(name = "SAVINGS_CURRENCY", nullable = false)),
@WriteTransformer(
transformerClass = MoneyAmountWriteTransformer.class,
column = @Column(name = "SAVINGS_BALANCE", nullable = false))
})
private Money savings;
これはうまくいきます。問題なくエンティティを読み込んで保存できます。
埋め込まれた Money インスタンスの属性に基づいてエンティティの JPQL クエリを実行しようとすると、問題が発生します。
SELECT t FROM Thing t WHERE t.savings.amount > 0;
これは以下を返します:
org.eclipse.persistence.exceptions.JPQLException:
Exception Description: Problem compiling [SELECT t FROM Thing t WHERE t.savings.amount > 0].
[29, 45] The state field path 't.savings.amount' cannot be resolved to a valid type.
この種のことは、Hibernate で問題なく機能しました (UserTypes と @Type アノテーションを使用)。
また、起動時に次のメッセージにも注意しました。
[EL Config]: metadata: 2013-04-28 15:30:04.276--Thread(Thread[main,5,main])--The default table generator could not locate or convert a java type (null) into a database type for database field (THING.SAVINGS_CURRENCY). The generator uses java.lang.String as default java type for the field.
[EL Config]: metadata: 2013-04-28 15:30:04.276--Thread(Thread[main,5,main])--The default table generator could not locate or convert a java type (null) into a database type for database field (THING.SAVINGS_BALANCE). The generator uses java.lang.String as default java type for the field.
これらのメッセージは、@WriteTransformer ごとに @Column 属性で columnDefinition を定義すると消えます。
問題は何ですか?私の疑いは、トランスフォーマーで何かが正しくないということです。おそらく、どこかにタイプヒントを設定していないのでしょう。しかし、それは自明ではなく、例はほとんどありません。