我正在Hibernate中执行本机查询,我想将结果集转换为MyDto列表。
使用本机查询时,我们通常遵循以下模式:
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)。但是对于本机查询,我们通常使用java.util.Date作为Dto类的变通方法。我希望在我们的Dtos中保持Joda类型(LocalDate,Instant等)与我们的实体保持一致。
我在网上找到了一个解决方法:
// 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 :(得分:0)
我找到了一个更简单的解决方法,我可以简单地将setter添加到我的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).
修复程序正在更改我的setter名称:
public void setCustomSetterForBirthDate(...
在我的查询中,我将birth_date列别名为customSetterForBirthDate:
String query = "SELECT ..., birth_date as customSetterForBirthDate ..."