-->
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: CGLib proxy ClassCastException returning "this" in
PostPosted: Mon Aug 25, 2008 11:01 am 
Newbie

Joined: Wed Jul 05, 2006 8:24 pm
Posts: 6
I tried looking up some other user forums on this and I dont see the solution to my problem. I read about de-proxy and visitor pattern solutions but thats not what I want.
Problem:
I'm trying to use a hibernate object to return its subclass using a given method.
Ex. A extends B extends AbstactAB
Code:
class abstract AbstractAB{
public A getA()
{
    return (A)this;   // this way throws class cast in calling code
    return new A();  // this way works fine but obviously not what i want
}

//calling code
A obj = b.getA();   //ClassCastException

for the record i'm actually using the visitor pattern below to get subclass,
after some digging the visitor way is doing this the same thing above, so i suspect its not a visitor problem its something to do with hibernate implementation of proxying an instance.

Code:
class AbstractAB{
  private Visitor v = new SubClassVisitor()
  public abstract accept(Visitor v);
  public A getA()
  {
      accept(v);
      return  v.getA();
   }
}

public class A
{
    public void accept(Visitor v)
    {
         v.visit(this);
    }
}

Public class SubClassVisitor implements Visitor
{
   private A a;
     public void visit(A a)
     {
          this.a = a;
     }
    public A getA()
    {
          return a;
     }
}


I dont want to turn lazy loading off and I really dont want to use some deproxy method, is there some way around this? I had a solition where created some static class that returns A off the proxy object B but i dont what to use it that way. It would be nice to have the get subclass method on the object itself.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 27, 2008 11:30 am 
Newbie

Joined: Wed Jul 05, 2006 8:24 pm
Posts: 6
I found the answer I did some digging in source for hibernate 3.2 core and found that when CGLIBLazyInitializer.invoke is called on my get method and it checks to see if the instance returned is "==" to the target held by the proxy. Because the visitor pattern allows me to get a hold of the target instance, if I try to return it, CGLIBLazyInitializer will check to see if it's referencing the same target and just give me back the proxy instead. ***Interesting Dont know why***
so when I say A subClassObj = b.getA(); proxy will try to be cast by my type.

Code:
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
...
if ( result == INVOKE_IMPLEMENTATION ) {
            Object target = getImplementation();
            try {
               final Object returnValue;
               if ( ReflectHelper.isPublic( persistentClass, method ) ) {
                  if ( ! method.getDeclaringClass().isInstance( target ) ) {
                     throw new ClassCastException( target.getClass().getName() );
                  }
                  returnValue = method.invoke( target, args );
               }
               else {
                  if ( !method.isAccessible() ) {
                     method.setAccessible( true );
                  }
                  returnValue = method.invoke( target, args );
               }
               return returnValue == target ? proxy : returnValue;
            }
            catch ( InvocationTargetException ite ) {
               throw ite.getTargetException();
            }
         }
...


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.