-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: eagerly fetching collections for entities(n+1 problem)
PostPosted: Tue Apr 21, 2015 4:32 pm 
Newbie

Joined: Tue Apr 21, 2015 4:30 pm
Posts: 1
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? :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.