Использование Projecions для извлечения определенного столбца из дочерней таблицы

У меня две таблицы

Loan (id, amount, duration)

LoanStatus(id, status, loan_id)   // just an example, but it has lot more fields in this table

Loan.java

public class Loan{

    private int id;
    private int amount;
    private int duration;
    private LoanStatus loanStatus;

    // getter and setters

}

LoanStatus.java

public class LoanStatus{   // just an example, but it has many fields than what actually given

    private int id;
    private String status;
    private Loan loan;

    //getter and setters

}

Теперь хотелось бы получить только amount, duration, loanStatus.status используя проекции. Я использовал createAlias() чтобы успешно извлечь этот конкретный столбец, но проблема возникает при установке его для установщика.

Criteria criteria = getSession().createCriteria(Loan.class,"loan");
    criteria.createAlias("loan.loanStatus", "loanStatus")
            .setProjection(Projections.projectionList().add(Projections.property("id"),"id")
            .add(Projections.property("amount"),"amount")
            .add(Projections.property("duration"),"duration")
            .add(Projections.property("loanStatus.status"), "loanStatus"))
            .add(Restrictions.eq("id", id))
            .setResultTransformer(Transformers.aliasToBean(Loan.class));
    return criteria.list();

У меня есть ошибка, которая заключается в следующем.

IllegalArgumentException occurred while calling setter for property [com.site.dto.Loan.loanStatus (expected type = com.site.dto.LoanStatus)]; target = [com.site.dto.Loan@4083974a], property value = [Pending]

Таким образом, я получаю ожидаемое значение столбца "Ожидание", но проблема заключается в том, чтобы установить его в сеттер. Я видел много вопросов для проекций, но большинство из них основывалось на ограничениях с использованием проекций, а не на выборке конкретного столбца ребенка с использованием проекций.

1 ответ

Решение

Напишите свой собственный трансформатор. Следующая реализация может быть именно то, что вам нужно

https://github.com/samiandoni/AliasToBeanNestedResultTransformer. Пример использования, как написано в их документах

class Person {
  private Long id;
  private String name;
  private Car car;
  // getters and setters
}

class Car {
  private Long id;
  private String color;
  // getters and setters
}

List<Person> getPeople() {
  ProjectionList projections = Projections.projectionList()
    .add(Projections.id().as("id"))
    .add(Projections.property("name").as("name"))
    .add(Projections.property("c.id").as("car.id"))
    .add(Projections.property("c.color").as("car.color"));

  Criteria criteria = getCurrentSession().createCriteria(Person.class)
    .createAlias("car", "c")
    .setProjection(projections)
    .setResultTransformer(new AliasToBeanNestedResultTransformer(Person.class));

  return (List<Person>) criteria.list();
}

// each car of Person will be populated
Другие вопросы по тегам