我正在 Hibernate 中执行 native 查询,我想将结果集转换为 MyDto 的列表。
使用 native 查询时,我们通常遵循以下模式:
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)。但对于 native 查询,我们通常在 Dto 类中使用 java.util.Date 作为解决方法。我更愿意在 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 将照常执行其余的操作。
有人做过类似的事情吗?
最佳答案
我找到了一个更简单的解决方法,我可以简单地将 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 ..."
关于java - 自定义类型/转换器与 Hibernate 的 Transformers.aliasToBean 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39497294/