-->
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: Can I set lazy value at runtime?
PostPosted: Fri Apr 29, 2005 3:00 am 
Newbie

Joined: Thu Apr 28, 2005 6:48 am
Posts: 12
Location: Finland
Hi,

Is it possbile to set lazy value at runtime? For certain session?

Most of the time I don't need whole object graph to be initialized, but in some occasions I do, so I need to change it at runtime.
I cannot use join fetch feature, because there is kind of subassociation
A contains set of B classes, B containss set of C classes.

So, I need to make Hibernate act as lazy value is set to false/true in certain session, can it be done?


Thank you


Hibernate version:2.1


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 02, 2005 6:37 am 
Newbie

Joined: Thu Apr 28, 2005 6:48 am
Posts: 12
Location: Finland
There is one solution that works at least with little testing.

This solution uses new persister subclass, that enables setting lazy-value at runtime. It may sound little complicated but it is not, and there is no any special tricks used. No other functionality is either added to persister than ability to set lazy value, and it is direct subclass from BasicCollectionPersister, that is default implementation to persists collections.

I use, at this moment, at this project, Hibernate version 2.1, and if there is ready-made functionality to set lazy value at runtime in Hibernate version 3.x, I honestly recommend to use it instead.

Any comments?


How-to-use instruction is included in code-comments.

Code:

/* Copyright © 2005 Ohjelmistotalo Arkki
*
* Luotu 2.5.2005
*
*/
package test;

import java.util.HashMap;
import java.util.Map;

import net.sf.hibernate.MappingException;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cache.CacheException;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.collection.BasicCollectionPersister;
import net.sf.hibernate.engine.SessionFactoryImplementor;
import net.sf.hibernate.mapping.Collection;

/**
* Custom persister with you can set value of lazy property at runtime.
*
* Using this util class to chage lazy value at runtime should affect same way as
* changing lazy value from configuration file. But I made only quick testing, and I'm
* quite newbie with Hibernate, so I can't guarantee anything.
*
* To use:
*
* Add to Hibernate's entity mapping file(user.hbm.xml for example),
* to collection association configure element, property
* <code>persister="this class"</code>
*
* for example, (association beetween users and roles)
* &lt; set name="roles" table="user_role" lazy="true" persister="test.MyBasicCollectionPersister" &gt;
*
* As you can see, lazy value can be setted, and it is handled as default value.


* In runtime you then use this persister as follows:
*
* Let's say that we have entity class <code>entity.User</code>, which contains set
* of roles, property named <code>roles</code>. So role name for this association in
* Hibernate is, by default at least, <code>entity.User.roles</code>, that is name that
* persister is binded with. So here is how you can change lazy property of that association
* in runtime.
*
* <code>
* Session session = ...open session as normally...
* ...open transaction as normally ...
*
* MyBasicCollectionPersister.getPersister( session.getSessionFactory(), "entity.User.roles").setLazy( false );
*
* ...do query as normally...
*
* ...commit transaction...
* ...close session...
* </code>
*
* And that's it.
*
* You can set default value by calling setLazyDefault(), instead of setLazy(boolean).
*
* @author Kari Surakka
*/
public class MyBasicCollectionPersister extends BasicCollectionPersister {
    // Map of maps
    public static Map persiterMaps = new HashMap();
   
    // Thread specific lazy values(java.lang.Boolean)
    public final ThreadLocal lazyValues = new ThreadLocal();

    /**
     * Creates new persister, and binds created persister to role name, so it can
     * be accessed by static method getPersister( SessionFactory, String ).
     * 
     * @param collection
     * @param cfg
     * @param factory
     * @throws MappingException
     * @throws CacheException
     */
   public MyBasicCollectionPersister(Collection collection, Configuration cfg, SessionFactoryImplementor factory)
      throws MappingException, CacheException {
       super(collection, cfg, factory);
       System.out.println("Factory "+factory );
       System.out.println("My persister "+this.getRole() );
       this.addPersister( factory, this.getRole() );
      
   }   
   
   /**
    * Binds this persister to session factory and to role. It has to be binded to both,
    * because there is one persister object(I think) per one session factory per role. 
    *
    * @param sessionFactory binding key
    * @param role binding key
    */
   private void addPersister( SessionFactory sessionFactory, String role ) {
       Map persiters = (Map)persiterMaps.get( sessionFactory );
       if (persiters==null) {
           persiters = new HashMap();
           persiterMaps.put( sessionFactory, persiters);
       }
      
       // Exposin self reference, but should not be critical here
       persiters.put( role, this);      
   }
   
   /**
    * Returns persister binded to session factory and to role. Returns null if there
    * is no persiter binded.
    *
    * @param factory
    * @param role
    * @return binded persister
    */
   public static MyBasicCollectionPersister getPersister( SessionFactory factory, String role ) {
       Map persisters = (Map)persiterMaps.get( factory );
       if (persisters!=null) {
          return (MyBasicCollectionPersister)persisters.get( role );          
       } else {
           return null;
       }
   }
   
   /**
    * Sets lazy-value for this persister for current thread
    * @param lazy value to set
    */
   public void setLazy( boolean lazy ) {
       lazyValues.set( new Boolean(lazy) );
   }
   
   /**
    * Sets default(configuration) value of lazy property for this persister.
    * Functionality is same as <code>perister.setLazy( persister.isLazyDefault() )</code>
    */
   public void setLazyDefaulft() {
       this.setLazy( this.isLazyDefault() );
   }
   
   /**
    * Returns default(configuration) value of lazy of this persister.
    * @return default value of lazy
    */
   public boolean isLazyDefault() {
       return super.isLazy();
   }
   
   /**
    * Returns lazy-value of this persister for current thread.
    * If lazy value is not setted with setLazy(boolean) method, returns
    * default(configuration) value of lazy property for this persister.
    *
    * @return runtime setted value of lazy property
    */
   public boolean isLazy() {
       Boolean boolObject = (Boolean)lazyValues.get();
       boolean lazy = boolObject!=null ? boolObject.booleanValue() : this.isLazyDefault();
       System.out.println("lazy value :"+lazy);      
       return lazy;
   }

}




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.