-->
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.  [ 8 posts ] 
Author Message
 Post subject: Strange behaviour on fetch = FetchType.EAGER in @OneToMany
PostPosted: Sat Aug 26, 2006 4:14 pm 
Newbie

Joined: Sat Aug 26, 2006 3:56 pm
Posts: 1
Hibernate version:
Hibernate Annotations 3.2.0.CR1
Hibernate 3.2 cr2
Name and version of the database you are using:
MySQL 5.0.24-standard

Hi,

When I'm using @OneToMany(fetch = FetchType.EAGER) the rows in my parent table are doubling when i fetch them.

To specify more clearly I have made an example using almost the same code as in the documentation with Troop and Soldier. The code I use can be found at http://folk.ntnu.no/erikaxel/hibernate/ There I also have the listing of the tables I am using.

The point of interest is in Troop.java:
Code:
@OneToMany(mappedBy = "troop", cascade = {CascadeType.REMOVE}, fetch = FetchType.EAGER)
public List<Soldier> getSoldiers() {
     return soldiers;
}


When I try to list all Troops with:
Code:
Session session = sessionFactory.openSession();
Transaction tx;
tx = session.beginTransaction();
List<Troop>list = session.createCriteria(Troop.class).list();
for(Troop troop : list)
   System.out.println("Troop id:" + troop.getId());
tx.commit();


I get the following output
Troop id:1
Troop id:2
Troop id:2
Troop id:3
when I am using fetch = FetchType.EAGER as specified above. If I remove that but keep everything else I get
Troop id:1
Troop id:2
Troop id:3
as expected.

In the tables troop 1 has 1 soldier, troop 2 has 2 soldiers and troop 3 has 0 soldiers.

I have tried to search the forums and the JIRA but haven't found anything. To me this looks like a bug, but I thought I would post it here first in case I'm wrong. If this is wanted behaviour, please let me know.

-- Erik Axel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 31, 2006 4:09 am 
Newbie

Joined: Thu Aug 31, 2006 4:05 am
Posts: 5
Hi,

I'm seeing this too. It's a serious problem for us as I can't simply replace the EAGER with a LAZY fetch strategy (though it would be better, agreed).

I don't know if it's a Hibernate Core problem (fixed in CR4 ?) or an annotations one (as annotations are not compatible with CR4 yet, can't say).


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 04, 2006 7:41 am 
Beginner
Beginner

Joined: Sun Jan 22, 2006 6:56 am
Posts: 29
I think with criteria queries with joins you need to add
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) to avoid the duplicate results.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 04, 2006 9:19 am 
Newbie

Joined: Thu Aug 31, 2006 4:05 am
Posts: 5
Well, I'm quite new to Hibernate, but the main reason why I can't just replace EAGER with LAZY is that I use a generic class for DAOs. The problem with it is that the session is lost, so calling lately getXXXX() on collections throws a session not found error.

BTW, how could I tune this code in order to get the fix working ?

Code:
public abstract class ADaoPrototype<TBean extends AHibernateBean> extends HibernateDaoSupport implements IDao<TBean> {

   private Class<TBean> thePersistentClass;

   private Class<TBean> getBeanClass() {
      if (thePersistentClass != null) return thePersistentClass;
      thePersistentClass = (Class<TBean>) ((ParameterizedType) getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];
      return thePersistentClass;
   }

   public TBean findById(Serializable id) {
      return (TBean) this.getHibernateTemplate().get(this.getBeanClass(), id);
   }

   public void save(TBean aBean) {
      this.getHibernateTemplate().saveOrUpdate(aBean);
   }

   public void update(TBean aBean) {
      this.getHibernateTemplate().update(aBean);
   }

   public List<TBean> getAll() {
      return this.getHibernateTemplate().loadAll(this.getBeanClass());
   }

   public void remove(TBean aBean) {
      this.getHibernateTemplate().delete(this.getHibernateTemplate().load(this.getBeanClass(), aBean.getSerializableId()));
   }

   public void closeSession() {
      this.getSessionFactory().close();
   }
}

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 04, 2006 11:28 am 
Beginner
Beginner

Joined: Sun Jan 22, 2006 6:56 am
Posts: 29
melix, do you have the same problem (duplicates entries in query result) as the thread starter or are you hijacking the thread? ;)

Anyway if you have the same problem, then the only method that could possibly cause this problem is the getAll method (because it's the only one that returns a list)

So I suggest you try to replace

Code:
return this.getHibernateTemplate().loadAll(this.getBeanClass());


With:

Code:
DetachedCriteria c = DetachedCriteria.forClass(this.getBeanClass());
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return this.getHibernateTemplate().findByCriteria(c);


HTH


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 04, 2006 11:32 am 
Beginner
Beginner

Joined: Sun Jan 22, 2006 6:56 am
Posts: 29
BTW, using eager fetching on collections as a rule is rarely the solution (unless you have a small data model or don't care about performance). Lazy is on by default for a good reason.
There are other solutions for avoiding all those LazyInitializationExceptions. For example of a pretty sophisticated technique, google for "Open Session In View".


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 04, 2006 11:37 am 
Newbie

Joined: Thu Aug 31, 2006 4:05 am
Posts: 5
I do have the same problem : replacing LAZY with EAGER fixes the problem ;) I'll try your fix and try to see if it works fine for me.

Tx.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 05, 2006 3:28 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Just to be clear, this is not a problem but a behavior (the correct approach has been described before).
And get rid of hibernateTemplate, use the plain APIs

_________________
Emmanuel


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

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.