4

在过去的几周里,我一直在使用 spring 和 hibernate,并且我一直在那里学习新的东西。

现在我有一个问题,我想用 Hibernate 中的 Projections 来解决。

假设有一个模型Person并且该模型有很多Car. 以下是类定义的大致样子:

public class Person implements java.io.Serializable {
    private Integer id;
    private String name;
    private List<Car> cars;
    private Integer minYear; // Transient
    private Integer maxYear; // Transient
}

public class Car implements java.io.Serializable {
    private Integer id;
    private Integer year;
}

这里的问题是我想让每个人的minYear( )由他们拥有的最早一年(最近一年)填充。maxYearPersoncars

后来我找到了一个可以使用的解决方案,Projections但我偶然发现了org.hibernate.QueryException: could not resolve property: minYear of: model.Person这里是 db 操作的代码:

Criteria criteria = sessionFactory.getCurrentSession().createCriteria("model.Person");
            criteria.add(create(personInstance));
            criteria.createAlias("minYear", "minYear");
            criteria.setProjection(Projections.min("cars.year").as("minYear"));

无论如何要使用瞬态方法存储聚合值,Projections因为我只想尽可能避免使用普通的 SQL 和 HQL。

4

1 回答 1

6

没关系,我已经找到了解决方案。

  1. 首先,我们需要像这样创建关联对象的别名

    Criteria criteria = sessionFactory.getCurrentSession().createCriteria("model.Person");
    criteria.createAlias("cars", "cars");
    
  2. 使用 Hibernate Projections 选择需要的

    ProjectionList projections = Projections.projectionList();
    projections.add(Projections.property("id").as("id"));
    projections.add(Projections.property("name").as("name"));
    projections.add(Projections.property("cars").as("cars"));
    
  3. 根据根实体对结果进行分组(在本例中使用其 id,Person.id),特别是在与聚合一起使用以对聚合进行分组时需要这样做

    projections.add(Projections.groupProperty("id"));
    
  4. 使用聚合函数

    projections.add(Projections.min("cars.year").as("minYear"));
    projections.add(Projections.max("cars.year").as("maxYear"));
    
  5. 设置投影

    criteria.setProjection(projections);
    
  6. 使用结果转换AliasToBeanResultTransformer器将结果字段(如步骤 2 和 4 中指定)映射到 POJO

    criteria.setResultTransformer(new AliasToBeanResultTransformer(Person.class));
    
  7. 得到结果

    List<Person> results = (List<Person>) criteria.list();
    
于 2013-05-26T16:15:38.630 回答