使用Projections从子表中获取特定列

时间:2015-03-01 17:03:54

标签: java mysql hibernate projection

我有两张桌子

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

}

现在,我希望仅使用预测获得amountdurationloanStatus.status。我已使用createAlias()成功获取该特定列,但在将其设置为setter时会出现问题。

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]

所以我获得了预期的列值"待定",但问题是将其设置为setter时。我已经看到很多关于预测的问题,但是大多数都是基于使用预测的限制而不是使用投影来获取孩子的特定列。

1 个答案:

答案 0 :(得分: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