2013-10-02 42 views
6

我有日期時間性質的實體堅持用休眠如何喬達日期時間轉換成JPA本機查詢

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") 
@Column(name = "EFF_DT") 
protected DateTime effDt; 

這一切運作良好和良好的定期彈簧數據的JPA生成的查詢。

我想添加自定義本地查詢

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
    Integer countEffDateBetween(DateTime start, DateTime end); 

我的錯誤是,當試圖調用這是

java.sql.SQLException: ORA-00932: inconsistent datatypes: expected DATE got BINARY 

這是我用來獲取與普通彈簧同樣的錯誤-data finders將自定義類型映射添加到我的實體之前

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") 

如何使彈簧-data-jpa/hibernate使用參數的自定義類型映射到本地查詢?

+0

你找到這個答案? –

+0

@WojciechGórski不,我沒有找到解決辦法。最後,我設法在JPA中重新編寫查詢,然後hibernate @Type註釋開始處理來自nz.co.vodafone.wcim的類型轉換'@Query(「select count(ch.circuitId)。 model.CircuitStateLog ch其中ch.effDt介於?1和?2之間以及ch.state =?3「)' –

回答

0

你的財產正好被設置爲java.util.Date這樣

然後在您的getter/setter

public DateTime getEffDt() { 
    return null == effDt ? null : new DateTime(effDt); 
} 

public void setEffDt(final DateTime effDt) { 
    this.effDt = null == effDt ? null : effDt.toDate(); 
} 

原住民轉換:

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
Integer countEffDateBetween(Date start, Date end); 
+0

這是避免使用DateTime的有趣解決方法,但在我們的情況下,我們希望將該字段保留爲DateTime。 –

+0

爲什麼不能將'countEffDateBetween(DateTime start,DateTime end);'改成'countEffDateBetween(Date start,Date end);'?這將使您能夠將您的屬性保留爲DateTime。 –

+1

我們使用的是DateTime,而不是java.util.Date。當然,如果我們停止使用DateTime並使用Date,我們就不會遇到這個問題。不過,我們希望使用遠遠優越的joda DateTime API。我的問題是'如何使本機查詢與DateTime一起工作',不使用DateTime不是這個問題的解決方案。 –

0

在類似情況下我訴諸寫一個自定義的CompositeUserType存儲Joda DateTime在兩個字段,一個dateti我的領域和時區領域。

當實體保存時,它將時間值存儲爲UTC,並將時區存儲爲原始值,在檢索時它將做相反的處理(即將存儲在數據庫中的時間轉換回原始時區)。

正如您在上面已經確定的那樣,雖然像「datetime BETWEEN?1 AND?2」這樣的查詢具有直觀的意義,當然這對於複合類型來說是沒有意義的,因爲您需要牢記時區。這是我以UTC存儲所有值的原因,所以我總是可以比較數據庫上的任何兩個日期/時間值。

不幸的是,這意味着我傳遞的所有日期/時間查詢參數必須轉換爲UTC。

0

準確地說我也得到了相同的要求。我通過註冊自定義類型到休眠配置來解決它。

對於本機查詢,TypeDefs不足以讓hibernate找到用戶類型。它需要類型解析器來查找它的類型。

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
    Integer countEffDateBetween(DateTime start, DateTime end); 

在這種情況下,hibernate嘗試從類型解析器中猜出類型(org.joda.time.DateTime)。

Type type = session.getFactory().getTypeResolver().heuristicType(typename); 

由於沒有解析器的DateTime.Then是越來越默認類型(序列化類型)。而日期時間的值被強制轉換爲它的類型,即序列化和數據庫,它是失敗的,由於持續以較大的二進制值。

要解決這個問題,你需要註冊DateTime類型到Hibernate配置爲

configuration.registerTypeOverride(new org.jadira.usertype.dateandtime.joda.PersistentDateTime(), new String[]{"org.joda.time.DateTime"});