2016-09-14 166 views
1

我在Hibernate中執行本機查詢,我想將結果集轉換爲MyDto的列表。自定義類型/轉換器結合休眠的變形金剛.aliasToBean

當使用原生查詢,我們通常遵循這樣的模式:

String query = "SELECT first_name as firstName, birth_date as birthDate ..." 

def results = session.createSQLQuery(query) 
    .setResultTransformer(Transformers.aliasToBean(MyDto.class)) 
    .list(); 

問題是,我們正在使用喬達時間爲我們的約會類(在這種情況下,生日是一個LOCALDATE的)。在正常的Hibernate查詢中,這很好(我們有我們自己的簡單用戶類型)。但對於原生查詢,我們通常在我們的Dto類中使用java.util.Date作爲解決方法。我寧願將Joda類型(LocalDate,Instant等)保留在我們的Dtos中以與我們的實體保持一致。

我找到了一個解決方法網上是這樣的:

// GrailsLocalDate is our custom UserType class for joda's LocalDate class 
Type localDateType = new TypeLocatorImpl(
    new TypeResolver()).custom(GrailsLocalDate.class); 

def results = session.createSQLQuery(query) 
    .addScalar("birthDate", localDateType) 
    .setResultTransformer(Transformers.aliasToBean(CorrespondentAssociateDto.class)) 
    .list() 

的問題是,一旦我作出addScalar呼叫時,它似乎改變地方與addScalar要求我必須指定所有列的行爲。所以如果我的查詢選擇10-15列,我需要添加10-15個addScalar調用。而如果我沒有任何自定義轉換,我不需要任何addScalar調用,並且aliasToBean僅基於將結果集別名與DTO的字段名稱進行匹配而進行映射。我希望我可以指定給定的列的一​​個變壓器,然後aliasToBean會照常休息。

有沒有人做過類似的事情?

回答

0

我發現了一個簡單的解決辦法,我可以簡單地添加setters來我的DTO是這樣的:

public void setBirthDate(java.util.Date d) { 
    if (d == null) { 
     this.birthDate = null; 
    } else { 
     this.birthDate = new LocalDate(d.getTime()); 
    } 
} 

...當然你可以換行到一個單一的工具方法。


編輯:這導致問題在代碼的其他地方,我們正在做的:

myDto.birthDate = someLocalDate // implicitly calls setBirthDate(java.util.Date). 

的修復正在改變我的二傳手名稱:

public void setCustomSetterForBirthDate(... 

而在我的詢問,我別名作爲customSetterForBirthDate的birth_date列:

String query = "SELECT ..., birth_date as customSetterForBirthDate ..."