2013-04-28 42 views
1

我正在使用EclipseLink 2.4.2。如何查詢使用EclipseLink @ReadTransformer和@WriteTransformer映射的@Entity屬性的屬性?

我有一個類型爲Money的屬性@Entity,它是外部庫的最終類。貨幣實例是不可變的,必須堅持爲兩列,一列爲金額,一爲貨幣。

我使用的是@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; 

這種運作良好;我可以加載並保存沒有問題的實體。

問題是當我試圖爲基於嵌入式錢實例的屬性的實體執行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

您應該將Money映射爲Embeddable/Embedded關係,而不是使用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

+0

好吧,這肯定是工作。 [相關的DescriptorCustomizer示例](http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Customizers#DescriptorCustomizer_example)。基本上,我將不得不爲每個嵌入任何不可變值類型(如Money)的實體創建一個DescriptorCustomizer,然後使用@Customizer爲每個這樣的實體註釋。 這當然有效,但它是痛苦的。也許是時候重新考慮直接從外部庫中嵌入不可變的值類型 - 或者切換回Hibernate。 – 2013-04-29 15:21:27