-->
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.  [ 2 posts ] 
Author Message
 Post subject: Filter the lazy collection two times within one Session
PostPosted: Sun Nov 22, 2009 7:18 am 
Newbie

Joined: Wed Aug 09, 2006 8:06 am
Posts: 2
Hello,

In my project I have a situation which can be described with imagined example below:
Code:
@Entity
@Table(name="army")
@FilterDef(name="pupilsWithGivenBirthDate", parameters={@ParamDef( name="maxDate", type="date" ), @ParamDef( name="minDate", type="date" )})
public class SchoolTO implements PersistentEntity {
/* ... some definitions */

   @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
   @ForeignKey(name="school_to_pupuils_fk", inverseName="pupils_to_school_fk")
   @JoinColumn(name="persistent_school_id" )
   @OrderBy("birth_date ASC")
   @Filter(name = "pupilsWithGivenBirthDate", condition = "birthDate>= :minDate AND birthDate <= :maxDate")
   private List<PupilTO> pupils = new ArrayList<PupilTO>(0);   // I need to have it initialized at start..

   public List<PupilTO> getPupils() {
      return pupils;
   }
}

@Entity
@Table(name="pupils")
public class PupilTO implements PersistentEntity {

   @Column(name="birth_date", nullable=false)
   private Date birth_date;

}


No within my business logic I have a session (BTW: this session is maitained by Spring framework internals... so I'm not bothering about setting it up). Now I want to get the pupils born within some given period... so I enable the filter on current session in order to limit the results:

Code:
Session currentSession = / * obtain the reference to current session */
Filter filter = currentSession.enableFilter("pupilsWithGivenBirthDate");
filter.setParameter("minDate ", new Date( /* some date */ ));
filter.setParameter("maxDate ", new Date( /* some date */ ));


Now whan I have this filter enabled than I can call to

Code:
School school = /* inittialize the school by hibernate... */
var filteredPupuils = school.getPupils() ;


Yes... so far so good.... but now I need to get the pupuils born in another period so I want to redefine the filter:

Code:
Session currentSession = / * obtain the reference to current session.. it's still the same session (!) */
currentSession.disableFilter("pupilsWithGivenBirthDate");
Filter filter = currentSession.enableFilter("pupilsWithGivenBirthDate");
filter.setParameter("minDate ", new Date( /* some other date than first time */ ));
filter.setParameter("maxDate ", new Date( /* some other date than first date */ ));


But when I call to school.getPupils() I don't get new collection of pupils but there is still collection of pupils retrived first time....

This might be in most situation the correct behaviour... The collection is lazy and after it has been initialized hibernate does not want to initialize it again... ok but what about filtering as described above?

I tried to dig into it a little bit, but I didn't find a nice solution for this. The easiest would be if I could set the ((AbstractPersistantCollection) school.getPupils()).initialized flag to false... in that case hibernate would reinitialize the collection as I wanted... but I didn't found any programatic way to do this (except maybe for hacking the sources of AbstractPersistentCollection to expose the initalized flag, but I don't want to do this of course).. what is more casting to AbstractPersistantCollection is at least not prefered way.

I also tried another dirty idea:
Code:
org.hibernate.collection.PersistentBag col = ((org.hibernate.collection.PersistentBag)school.getPupils());
SessionImplementor sess = col.getSession();
CollectionEntry ce = sess.getPersistenceContext().getCollectionEntry(col);
ce.getLoadedPersister().initialize( ce.getLoadedKey(), sess );


The query is fired agains the database, but this also fails since the collection is already initalized and does not want to read from obtained resultset (BTW: Hibernate.initalize(school) fails at the beginning since there because it checks the initalized flag of collection in the first place).

Ok enough dirty methods... Is there an way I can reinitialized the collection after enabling different filter.

The only reasonable solution which comes to my mind is to call execute HQL query (or rather use find method on HibernateTemple() since I'm using spring) but in this case I'm loosing the lightweight way of obtainting the collection by just calling school.getPupils().... so I'm loosing the benefit of annotations:(

BTW: switching to non lazy or fetching whole collection is not an option in my case since in my real project the collection is huuuuge :)


Top
 Profile  
 
 Post subject: Re: Filter the lazy collection two times within one Session
PostPosted: Mon Nov 23, 2009 10:34 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
Have you also thought of using the refresh()-method?

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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.