我正在使用EclipseLink 2.4.2。

我有一个@Entity,其属性类型为Money,这是来自外部库的最终类。 Money实例是不可变的,必须将其保留为两列,一列代表金额,一列代表货币。

我正在使用@ReadTransformer和两个@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,这些消息就会消失。

可能是什么问题?我的怀疑是这些转换器不正确,也许我没有在某个地方设置类型提示-但这不是很明显,示例很少而且相去甚远。

最佳答案

您应该将Money映射为可嵌入/嵌入关系,而不要使用TransformationMapping。这将允许对其进行查询,并且是标准的JPA。不知道您在谈论Hibernate时,TransformationMapping是特定于EclipseLink的,因此最肯定不能与Hibernate一起使用。

要启用对TransformationMappings的查询,可以使用QueryKey。您将需要使用DescriptorCustomizer定义列的查询键,然后将能够使用您给查询键指定的任何名称来查询JPQL中的列。在EclipseLink中,您还可以使用JPQL COLUMN()函数直接查询任何未映射的数据库列。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Query_Keys

http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/j_column.htm#column

07-25 20:38