1

我正在使用 EclipseLink 2.4.2。

我有一个属性为 Money 类型的 @Entity,它是来自外部库的最终类。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,这些消息就会消失。

问题可能是什么?我的怀疑是变形金刚出了点问题,也许我没有在某处设置类型提示 - 但它并不明显,示例很少而且相差甚远。

4

1 回答 1

1

您应该将 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

于 2013-04-29T13:48:05.643 回答