How to transform a flat result set using Hibernate

时间秒杀一切 提交于 2019-11-26 08:34:22

问题


Is it possible to map result of SQL to not flat object?

List<Customer> customers = hibernateSession().createCriteria(CustomerDetailsView.class)
                .add(Restrictions.in(\"userName\", userName))
                .setProjection(buildProjection())
                .setResultTransformer(Transformers.aliasToBean(Customer.class))
                .list();

In my case CustomerDetailsView has flat structure. But I need to map it to object like this:

public class Customer {
    private String userName;
    private String title;
    private String firstName;
    private String lastName;
    private String type;
    private String companyName;
    private AddressDetails addressDetails;
}

and

public class AddressDetails {
    private String countryCode;
    private String addressLine1;
    private String zipOrPostCode;
    private String city;
    private String countryDivisionName;
    private String countryDivisionCode;
    private String countryDivisionTypeCode;
    private String residentialAddress;
}

回答1:


Yes it is possible. You can use a custom transformer for it: FluentHibernateResultTransformer.

You can copy paste code, or add the jar by Maven: fluent-hibernate-core.

You need to use Criteria with Projections. Please, don't forget to specify projection aliases (userName, addressDetails.countryCode)

Criteria criteria = session.createCriteria(Customer.class);
criteria.createAlias("addressDetails", "addressDetails", JoinType.LEFT_OUTER_JOIN);

criteria.setProjection(Projections.projectionList()
        .add(Projections.property("userName").as("userName"))
        .add(Projections.property("addressDetails.countryCode")
        .as("addressDetails.countryCode")));

List<Customer> customers = criteria.setResultTransformer(
        new FluentHibernateResultTransformer(Customer.class)).list();

Using with HQL

It is impossible to use it with HQL, because of Hibernate doesn't allow nested aliases in HQL

select addressDetails.countryCode as addressDetails.countryCode

It will be an error with the addressDetails.countryCode alias.

Using with a native SQL

The transformer can be used for a native SQL with the nested projections (opposite HQL). It is need to use the aliases with the quotes in this case:

String sql = "select c.f_user_name as userName, d.f_country_code as \"addressDetails.countryCode\" "
        + "from customers c left outer join address_details d on c.fk_details = d.f_pid";

List<Customer> customers = session.createSQLQuery(sql)
        .setResultTransformer(new FluentHibernateResultTransformer(Customer.class))
        .list();


来源:https://stackoverflow.com/questions/36361256/how-to-transform-a-flat-result-set-using-hibernate

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