如何查询使用EclipseLink @ReadTransformer和@WriteTransformer映射的@Entity属性的属性?

时间:2013-04-28 23:07:45

标签: java jpa eclipselink jpql

我正在使用EclipseLink 2.4.2。

我有一个@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,这些消息就会消失。

问题可能是什么?我怀疑变形金刚有些不对劲,也许我并没有在某处设置类型提示 - 但这并不明显,例子很少而且很远。

1 个答案:

答案 0 :(得分: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