Java 自定义类型/转换器与Hibernate';s.aliasToBean
我正在Hibernate中执行一个本机查询,我想将结果集转换为MyDto的列表 使用本机查询时,我们通常遵循以下模式:Java 自定义类型/转换器与Hibernate';s.aliasToBean,java,hibernate,grails,Java,Hibernate,Grails,我正在Hibernate中执行一个本机查询,我想将结果集转换为MyDto的列表 使用本机查询时,我们通常遵循以下模式: String query = "SELECT first_name as firstName, birth_date as birthDate ..." def results = session.createSQLQuery(query) .setResultTransformer(Transformers.aliasToBean(MyDto.class))
String query = "SELECT first_name as firstName, birth_date as birthDate ..."
def results = session.createSQLQuery(query)
.setResultTransformer(Transformers.aliasToBean(MyDto.class))
.list();
问题是我们在日期类中使用Joda时间(在本例中,birthDate是LocalDate)。对于普通的Hibernate查询,这很好(我们有自己的简单用户类型)。但是对于本机查询,我们通常在Dto类中使用java.util.Date作为变通方法。我更愿意在DTO中保持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()
public void setBirthDate(java.util.Date d) {
if (d == null) {
this.birthDate = null;
} else {
this.birthDate = new LocalDate(d.getTime());
}
}
问题是,一旦我调用addScalar,它似乎就改变了我必须使用addScalar调用指定所有列的行为。因此,如果我的查询选择10-15列,我需要添加10-15个addScalar调用。然而,如果我没有任何自定义转换,我就不需要任何addScalar调用和aliasToBean,只要将resultset别名与DTO的字段名匹配即可。我希望我可以为给定的列指定一个转换器,然后aliasToBean将像往常一样指定其余的转换器
有人做过类似的事情吗?我发现了一个更简单的解决方法,我可以简单地将setter添加到我的数据中,如下所示:
// 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()
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(...
在我的查询中,我将出生日期列别名为customSetterForBirthDate:
String query = "SELECT ..., birth_date as customSetterForBirthDate ..."
我发现了一个更简单的解决方法,我可以简单地将setter添加到我的Dto中,如下所示:
// 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()
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(...
在我的查询中,我将出生日期列别名为customSetterForBirthDate:
String query = "SELECT ..., birth_date as customSetterForBirthDate ..."