-->
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.  [ 4 posts ] 
Author Message
 Post subject: Lazy Initialization Strategies?
PostPosted: Tue Nov 09, 2004 8:41 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
I've been considering a few ways I have to initialize my object graph where I use lazy initialization. I am sending the results in a SOAP message so it's necessary for me to inflate (or null out) parts of the graph before I send them off so I don't get the "lazy initialization" error. The problem is I don't necessarily want to dictate what pieces of the graph should or shouldn't be inflated, but would rather want the client to tell me what they need. Otherwise, things are pretty brittle if I have develop an inflation strategy for every client permutation of what pieces they want.

So I've looked around, and I've decided that in this case Hibernate.initialize() is probably my best bet (can't use Session-to-view because the graph is serialized). My question: is there a way to recursively inflate all the children of a parent node using .initialize() or do I need to recurse the object structure myself to run .initialize() on all the lazy elements?

TIA,
Lou

Hibernate version:
2.1.6
Mapping documents:

Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:

Name and version of the database you are using:

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 10, 2004 1:57 am 
Regular
Regular

Joined: Thu Nov 20, 2003 10:04 pm
Posts: 64
Location: Melbourne, Australia
I think you'd have to either traverse the graph yourself or the collections you need as non-lazy in the mapping.

Hibernate includes some metadata about the mapping that may be useful during a recursive traversal.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 10, 2004 2:08 am 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
Yeah, that's where I was sort of heading, but now I'm starting to wonder if it's really worth it anymore to even use lazy initialization. Recursing a graph that could potentially become very large is expensive, and probably more so then not using lazy initialization.

Another tact might be to just lazy initialize primary nodes of the graph and then turn it off for the children of those primary nodes. Then I would only need to worry about initializing the primary nodes.

An interesting problem nonetheless, thanks for your input, and I'd sure like to hear other's experience.

Lou


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 12, 2004 6:45 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
Ok, I coded a way to recurse through the object graph using Hibernate Metadata, but the strange thing is that I have the undesired effect of hydrating *all* the lazy objects, when all I want is the ones I pass in, called "inflatables." Does anyone know why this would be occuring?

Code:
    public void lazyInflateDeep(final SessionFactory sesFactory, Object object,
            Set inflatables) throws DaoException {
        try {
            Class objClass = object.getClass();
            ClassMetadata classMetadata = sesFactory.getClassMetadata(objClass);

            if (classMetadata == null) {
                // If here, then we are dealing with a CBLIB Proxy class and
                // must use the ProxyHelper to get the proxied class
                objClass = HibernateProxyHelper.getClass(object);
                classMetadata = sesFactory.getClassMetadata(objClass);
            }

            // get persistent properties
            Type[] propertyTypes = classMetadata.getPropertyTypes();
            String[] propertyNames = classMetadata.getPropertyNames();

            // for each persistent property of the bean
            for (int i = 0; i < propertyTypes.length; i++) {
                if (propertyTypes[i].isPersistentCollectionType()) {
                    CollectionMetadata collectionMetadata = sesFactory
                            .getCollectionMetadata(((PersistentCollectionType) propertyTypes[i])
                                    .getRole());

                    String propName = propertyNames[i];
                    Collection collection = (Collection) classMetadata
                            .getPropertyValue(object, propName);

                    if (collection != null && !collection.isEmpty()) {
                        if (collectionMetadata.isLazy()
                                && !Hibernate.isInitialized(collection)) {
                            if (inflatables.contains(propName)) {
                               Hibernate.initialize(collection);
                               log.info("Inflating: " + propName);
                            }
                        }
                        recurseAndInflateGraph(sesFactory, collection, inflatables);
                    }
                } else if (propertyTypes[i].isAssociationType()) {
                    String propName = propertyNames[i];
                    Object association = classMetadata
                            .getPropertyValue(object, propName);

                    if (association != null ) {
                        if (!Hibernate.isInitialized(association)) {
                            if (inflatables.contains(propName)) {
                               Hibernate.initialize(association);
                              log.info("Inflating: " + propName);
                           }
                        }
                    }
                }
            }
        } catch (HibernateException he) {
            log.warning("Hibernate Exception thrown: " + he);
            throw new DaoException(he);
        }

    }

    private void recurseAndInflateGraph(final SessionFactory sesFactory,
            final Collection collection, final Set inflatables) throws DaoException {
        for (Iterator iter = collection.iterator(); iter.hasNext();) {
            Object o = iter.next();
            lazyInflateDeep(sesFactory, o, inflatables);
        }
    }


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