Custom type / converter in conjunction with Hibernate's Transformers.aliasToBean

邮差的信 提交于 2021-01-28 23:40:48

问题


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();

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()

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?


回答1:


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.


Edit: 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(...

And in my query, I alias the birth_date column as customSetterForBirthDate:

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


来源:https://stackoverflow.com/questions/39497294/custom-type-converter-in-conjunction-with-hibernates-transformers-aliastobean

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!