I have two Entities @Entity @Table(name = "steps") public class Step { @Id @Column(nullable = false, insertable = true, updatable = true) private long id; //more fields @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "result_id", referencedColumnName = "id") private Result result;
and
@Entity @Table(name = "results") public class Result { @Id @Column(nullable = false, insertable = true, updatable = true) private long id; //more fields @OneToMany(mappedBy = "result", fetch = FetchType.EAGER) private List<Step> steps;
Now I need to get all results and their associated steps. I will want all the steps so an eager fetch seems best, and I know all results will have steps so an inner join will be fine. I will want to get only some more fields from results, but not all so I can maximize the use of an index, so projection will be needed.
To accomplish this I have tried two methods:
Query query = getSession().createQuery( "select distinct result from Result as result " + "inner join result.steps " + "where result.monitorId = :id " + "and result.completed between :from and :to "); query.setLong("id", monitorId); query.setTimestamp("from", from); query.setTimestamp("to", to);
for (Result result : query.list()) { result.getSteps() //work work }
Hibernate does a join like I wanted but when I start to iterate over the results, Hibernate logs one more select query per step I'm using. (I also haven't found a good way for projection if I'm going this route?)
The second approach I have tried seems great so far:
Criteria criteria = getSession().createCriteria(Result.class); criteria.setProjection(Projections.projectionList() .add(Projections.property("completed"), "completed") .add(Projections.property("steps"), "steps"));
criteria.add(Restrictions.eq("someId", someId)); criteria.add(Restrictions.between("completed", from, to)); criteria.setFetchMode("steps", FetchMode.JOIN); criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); criteria.setResultTransformer(Transformers.aliasToBean(Result.class));
The projections work great as long as I don't include steps. I'm guessing that has to do with it not belonging to the actual database table? When I do try with steps I get
java.lang.ArrayIndexOutOfBoundsException: 2
on criteria.list();
So my main question is, how do I best do eager fetching of some but not all columns in results + a collection of steps belonging to each result? Help please? :)
|