-->
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: instanceof for hibernate loaded object not working
PostPosted: Mon Mar 13, 2006 9:33 pm 
Newbie

Joined: Mon Mar 13, 2006 9:27 pm
Posts: 4
Hi, I'm using the latest stable hibernate and having a problem. When I run this code:

Code:
if (! (pi instanceof dataobs.puzzleobs.Puzzle3))
{
   System.out.println("Found p3 as: " + pi);
}


The following is printed out:
Code:
            Found p3 as: dataobs.puzzleobs.Puzzle3@175870a


As far as I know pi is an instance of Puzzle3, but the code doesn't work. :(

Am I doing something dumb? Obviously pi is loaded from the DB by Hibernate. If you need the mapping documents, I'd like to simplify them before posting.

Just a few notes:
pi is loaded as part of a collection in another object.
The object that I reference in Hibernate (and my objects) is an interface not a base class.

Is there some way to print out what class an object really is? The toString() seems to say Puzzle3, but I assume it could have been overridden by something that Hibernate does.

Thanks!

Nick


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 13, 2006 10:50 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
To print out an object's "real" class, use obj.getClass().getName(), or obj.getClass().getSimpleName(). You shouldn't use toString() like you're using it: in fact, you really should override toString in every class you write (according to Sun's own recommendations (see the javadocs for Object.toString())).

Presumably hibernate has proxied the object. If you've loaded the object as an interface, the actual class could be anything; you'll have to deproxy the object first in order to find the "real" class. Use Hibernate.initialize() or just access a member of the object to do that.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 14, 2006 2:36 pm 
Newbie

Joined: Mon Mar 13, 2006 9:27 pm
Posts: 4
Thank you for your help. I still haven't solved my problem yet.

I added the following code:

Code:
   Hibernate.initialize (p);
   Hibernate.initialize (p.getPuzzleList());
   PuzzleIfc pi = p.GetPuzzle(nPuzzleNum);
   Hibernate.initialize (pi);
   pi.DoNothing();
   String strxxx = pi.getClass().getName();
   System.out.println (strxxx);
        if (! (pi instanceof dataobs.puzzleobs.Puzzle3))
   {
      System.out.println("Found p3 as: " + pi);
   }



And I get the following printed out:

Code:
 
DoNothing
dataobs.puzzleobs.PuzzleIfc$$EnhancerByCGLIB$$61018aeb
Found p3 as: dataobs.puzzleobs.Puzzle3@8edb84


I can see the proxy object, but calling initialize on the objects and calling a member function doesn't change it. I must still be missing something. :(


-- Nick


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 14, 2006 5:02 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
A do-nothing function isn't going to help. It must be a function that calls one of the methods in the mapping file, as those are the methods that CGlib proxies. So if your class contains this element in its mapping:
Code:
  <property name="Title" column="COL_TITLE"/>
Then obj.getTitle() will do what you need.

Hibernate.initialize() should work, but I've noticed it doing nothing from time to time, myself. I've never bothered to chase down what's wrong, because calling an accessor (one of the mapped getXXX() methods) accomplishes the same thing.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 15, 2006 12:55 pm 
Newbie

Joined: Mon Mar 13, 2006 9:27 pm
Posts: 4
Thanks for your help so far. It has solved some of my problems. I still have one left relating to this issue.

I've found that when I have two classes derived from two different base classes that refer to each other (circular reference), one of them resolves to the derived class after being loaded by hibernate and the other resolves to a CGLib class and nothing I do can turn it into the original derived class. When I break the circular reference the problem goes away and both objects resolve to the proper derived class.

The other wierd thing is that when I look at the database, there is no difference between the case that works and the one that doesn't (except for the null reference of course). The table has a discriminator that knows the proper class.

Classify me still as a stuck newbie. I'll continue to read the docs, but if you can point me to anything particular, I'd appreciate it.

For reference I see the following objects when loading. One has the circular reference, one doesn't.

Code:
Loaded PI: -1(dataobs.puzzleobs.Puzzle2)
Loaded PI: -1(dataobs.puzzleobs.PuzzleIfc$$EnhancerByCGLIB$$bc638025)



--Nick


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 15, 2006 4:39 pm 
Newbie

Joined: Mon Mar 13, 2006 9:27 pm
Posts: 4
Well, I've solved my problem, but I still don't understand it. Here's what I found, in case it is useful to someone else.


1. I do a session.saveorupdate() on two derived objects with a circular reference.
2. The database looks good.
3. If I don't close/reopen the session, and do a session.CreateQuery() to 'load' the objects from the database, everything works great.
4. If I close/reopen the session (or close my app and restart it) one of the objects can't be resolved to it's derived class, it's always a CGLib class. (Note the two objects are derived from different base classes.)
5. The only fix that I found is to load my objects in a specific order (e.g. call CreateQuery() on one object type then the other). I'm not sure what the difference is between the objects -- I load last the one I saved first, but the objects are pretty similar, so I don't know what's going on.

Anyway, this solves it for me. I could still be doing something very wrong, but it cost me a couple of days.


--Nick


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.