Как преобразовать плоский набор результатов, используя Hibernate

Можно ли отобразить результат SQL на не плоский объект?

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

В моем случае CustomerDetailsView имеет плоскую структуру. Но мне нужно сопоставить его объекту так:

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

а также

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 ответ

Решение

Да, это возможно. Вы можете использовать собственный преобразователь: FluentHibernateResultTransformer.

Вы можете скопировать код вставки или добавить банку с помощью Maven: fluent-hibernate-core.

Вам нужно использовать Criteria с Projections, Пожалуйста, не забудьте указать псевдонимы проекции (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();

Использование с HQL

Его невозможно использовать с HQL, потому что Hibernate не допускает вложенные псевдонимы в HQL

select addressDetails.countryCode as addressDetails.countryCode

Это будет ошибка с addressDetails.countryCode псевдоним.

Использование с нативным SQL

Преобразователь может использоваться для нативного SQL с вложенными проекциями (напротив HQL). В этом случае необходимо использовать псевдонимы с кавычками:

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();
Другие вопросы по тегам