定制类型/转换器与Hibernate的Transformers.aliasToBean结合使用 [英] Custom type / converter in conjunction with Hibernate's Transformers.aliasToBean
问题描述
我正在Hibernate中执行本机查询,我想将结果集转换为MyDto的列表.
I'm executing a native query in Hibernate and I want to transform the result set into a List of MyDto's.
在使用本机查询时,我们通常遵循以下模式:
When using native queries, we typically follow this pattern:
String query = "SELECT first_name as firstName, birth_date as birthDate ..."
def results = session.createSQLQuery(query)
.setResultTransformer(Transformers.aliasToBean(MyDto.class))
.list();
问题在于我们将Joda-time用于日期类(在这种情况下,birthDate是LocalDate).对于普通的Hibernate查询,这很好(我们有自己的简单UserTypes).但是对于本机查询,我们通常在Dto类中使用java.util.Date作为解决方法.我希望在Dto中保持Joda类型(LocalDate,Instant等)与我们的实体保持一致.
The problem is we're using Joda-time for our date classes (in this case birthDate is a LocalDate). With normal Hibernate queries this is fine (we have our own simple UserTypes). But with native queries, we've typically used java.util.Date as a workaround in our Dto classes. I would prefer to keep the Joda types (LocalDate, Instant, etc.) in our Dtos to be consistent with our entities.
我在网上找到了一个解决方法,如下所示:
I found one workaround online like this:
// 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.
The problem is that once I make a call to addScalar, it seems to change the behavior where I must specify ALL columns with addScalar calls. So if my query is selecting 10-15 columns, I need to add 10-15 addScalar calls. Whereas if I didn't have any custom transformation I don't need any addScalar calls and aliasToBean simply maps based on matching the resultset alias to the DTO's field names. I was hoping I could just specify the one transformer for the given column and then aliasToBean would the rest as usual.
有人做过类似的事情吗?
Has anyone done something similar?
推荐答案
我找到了一个更简单的解决方法,我可以像这样简单地将setter添加到我的Dto中:
I found a simpler workaround, I can simply add setters to my Dto like this:
public void setBirthDate(java.util.Date d) {
if (d == null) {
this.birthDate = null;
} else {
this.birthDate = new LocalDate(d.getTime());
}
}
...,当然,您可以将其包装到单个实用程序方法中.
... and of course you could wrap that into a single utility method.
这在我们正在执行的代码中的其他地方引起了问题:
This caused problems elsewhere in the code where we were doing:
myDto.birthDate = someLocalDate // implicitly calls setBirthDate(java.util.Date).
此修复程序正在更改我的设置者名称:
The fix was changing my setter name:
public void setCustomSetterForBirthDate(...
在查询中,我将birth_date列的别名作为customSetterForBirthDate:
And in my query, I alias the birth_date column as customSetterForBirthDate:
String query = "SELECT ..., birth_date as customSetterForBirthDate ..."
这篇关于定制类型/转换器与Hibernate的Transformers.aliasToBean结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!