-->
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.  [ 6 posts ] 
Author Message
 Post subject: lazy loading + hibernate jars and pojos in diff. classloader
PostPosted: Thu Oct 26, 2006 2:40 pm 
Beginner
Beginner

Joined: Sun May 02, 2004 8:04 am
Posts: 36
Hi,

Is there any possible way for lazy loading to work such that my hibernate jars including cglib can live in one classloader and the POJO classes in another?
So far I can't see anyway since the cglib classes seem to create a new proxy instance requiring that the POJO is in the same classpath. Maybe this could be a feature enhancement

Thanks, Jason


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 11:25 am 
Newbie

Joined: Tue Dec 19, 2006 11:05 am
Posts: 11
Hi,

as we experienced it is possible to hibernate and cglib jars live in another classloader as the POJO classes. However there seems to be a little bug causing the created proxy (the interfaces it implements) to live in the classloader loading hibernate instead of the classloader for the POJOs. CGLIB uses the classloader for the first passed interface as default. Hibernate passes the interfaces in an arbitrary order. One of the passed interfaces is the HibernateProxy interfaces loaded together with hibernate in one classloader. If - by accident - this interface is passed first the proxy interfaces live in the wrong namespace.

We solved this problem by patching the class:
org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory
(CGLIBProxyFactory.java 9210 2006-02-03 22:15:19Z steveebersole)

In this class we fond the code:

Code:
  public void postInstantiate(
    final String entityName,
    final Class persistentClass,
    final Set interfaces,
    final Method getIdentifierMethod,
    final Method setIdentifierMethod,
    AbstractComponentType componentIdType)
  throws HibernateException {
    this.entityName = entityName;
    this.persistentClass = persistentClass;
    this.interfaces = (Class[]) interfaces.toArray(NO_CLASSES);
    this.getIdentifierMethod = getIdentifierMethod;
    this.setIdentifierMethod = setIdentifierMethod;
    this.componentIdType = componentIdType;
    factory = CGLIBLazyInitializer.getProxyFactory(persistentClass, this.interfaces);
  }

Which we replaced with the following code:

Code:
  public void postInstantiate(
    final String entityName,
    final Class persistentClass,
    final Set interfaces,
    final Method getIdentifierMethod,
    final Method setIdentifierMethod,
    AbstractComponentType componentIdType)
  throws HibernateException {
    this.entityName = entityName;
    this.persistentClass = persistentClass;
    this.interfaces = (Class[]) interfaces.toArray(NO_CLASSES);
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if(this.interfaces.length > 1) {
      Class firstIfc = this.interfaces[0];
      if(firstIfc.getName().startsWith("org.hibernate")) {
        this.interfaces[0] = this.interfaces[1];
        this.interfaces[1] = firstIfc;
        System.err.println("Replace: " + firstIfc.getName() + " by " + this.interfaces[0].getName());
      }
    }
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    this.getIdentifierMethod = getIdentifierMethod;
    this.setIdentifierMethod = setIdentifierMethod;
    this.componentIdType = componentIdType;
    factory = CGLIBLazyInitializer.getProxyFactory(persistentClass, this.interfaces);
  }

It would be of great interest if this is actually a bug in hibernate, and if it is planned to fix it....

Best regards,
Jan Wiemer
Code:


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 3:10 pm 
Beginner
Beginner

Joined: Sun May 02, 2004 8:04 am
Posts: 36
Hi,

That is very interesting-- I had thought that it had to do with the fact that it's not possible to set a classloader in the CGLIB code where it creates the proxy but I guess it is doing that.
I do agree this looks like a bug to me, I submitted it as

http://opensource.atlassian.com/project ... e/HHH-2317

Cheers, Jason


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 20, 2006 3:29 am 
Newbie

Joined: Tue Dec 19, 2006 11:05 am
Posts: 11
compare also http://opensource.atlassian.com/project ... e/HHH-2318


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 13, 2007 9:12 am 
Newbie

Joined: Mon Aug 13, 2007 9:05 am
Posts: 1
Wiemer wrote:


Bumbing this thread. Anything new on the status of the above issue?

Or: Is there any way to disable lazy loading in configuration when using JPA? Currently I've patched the hibernate to forcibly disable lazy loading, which is of course not very desirable.


Top
 Profile  
 
 Post subject: A fix
PostPosted: Tue Jan 15, 2008 8:05 am 
Newbie

Joined: Tue Jan 15, 2008 7:44 am
Posts: 1
Hi,

I've experienced a similar problem with Hibernate 3.1.3.

Changing the HibernateProxy.class to be last in the interfaces list seemed to help in my case: this way, the generated interfaces use the POJOs classloader rather than HibernateProxy's classloader.

Here's my patch:

Code:
$ diff -u orig/hibernate-3.1/src/org/hibernate/tuple/PojoEntityTuplizer.java new/hibernate-3.1/src/org/hibernate/tuple/PojoEntityTuplizer.java
--- orig/hibernate-3.1/src/org/hibernate/tuple/PojoEntityTuplizer.java  2006-03-20 22:19:36.000000000 +0200
+++ new/hibernate-3.1/src/org/hibernate/tuple/PojoEntityTuplizer.java   2008-01-15 12:55:40.690595600 +0200
@@ -5,6 +5,7 @@
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

@@ -90,8 +91,7 @@
        protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
                // determine the id getter and setter methods from the proxy interface (if any)
         // determine all interfaces needed by the resulting proxy
-               HashSet proxyInterfaces = new HashSet();
-               proxyInterfaces.add( HibernateProxy.class );
+               HashSet proxyInterfaces = new LinkedHashSet();

                Class mappedClass = persistentClass.getMappedClass();
                Class proxyInterface = persistentClass.getProxyInterface();
@@ -125,6 +125,8 @@
                                proxyInterfaces.add( subclassProxy );
                        }
                }
+
+               proxyInterfaces.add( HibernateProxy.class );

                Iterator properties = persistentClass.getPropertyIterator();
                Class clazz = persistentClass.getMappedClass();


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