简体   繁体   中英

Map hibernate projections result to java POJO model

I've been using spring and hibernate for this past few weeks and I've always been learning something new there.

Right now I've got a problem that I want to solve with Projections in Hibernate.

Suppose there is a model Person and that model has many Car . The following are how the class definitions roughly gonna look like:

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;
}

The problem here is I want to get the minYear ( maxYear ) of each Person to be filled by the earliest year (latest year) of the cars they have.

Later I found a solution to use Projections but I stumbled upon org.hibernate.QueryException: could not resolve property: minYear of: model.Person and here is the code of the db operation:

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

Is there anyway to store the aggregation value in transient method using Projections because I just want to avoid using plain SQL and HQL as much as possible.

Never mind, I've found the solution.

  1. First we need to create alias of the associated object like so

     Criteria criteria = sessionFactory.getCurrentSession().createCriteria("model.Person"); criteria.createAlias("cars", "cars"); 
  2. Select the needed using 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. Group the result based on the root entity (in this case using its id, Person.id), this is needed especially when used with aggregation to group the aggregation

     projections.add(Projections.groupProperty("id")); 
  4. Use the aggregate function

     projections.add(Projections.min("cars.year").as("minYear")); projections.add(Projections.max("cars.year").as("maxYear")); 
  5. Set the projection

     criteria.setProjection(projections); 
  6. Use result transformer AliasToBeanResultTransformer to map the result fields (as specified in step 2 & 4) to the POJO

     criteria.setResultTransformer(new AliasToBeanResultTransformer(Person.class)); 
  7. Get the result

     List<Person> results = (List<Person>) criteria.list(); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM