-->
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.  [ 8 posts ] 
Author Message
 Post subject: How to save objects of derived class?
PostPosted: Fri Jan 07, 2005 2:22 am 
Newbie

Joined: Wed Jul 07, 2004 11:15 pm
Posts: 6
Location: California, USA
Hello,

This is probably quite simple but I am not able to quite figure it out. Consider a class Outer which contains an objects of classes Inner1, Inner2, and Inne3. All the Inner classes extend the same class Inner and do not add any attribute to Inner.

I would like to save this by specifying hibernate-mapping for Outer and Inner, but this throws MappingException in net.sf.hibernate.impl.SessionFactoryImpl.getPersister because no ClassPersister can be found for Inner1.

If using the debugger insider this method I set the persister to be the same as that for Inner then the object is saved properly. Also, if I specify the exact same mapping for Inner1 as that for Inner then also the Outer and Inner are saved without error.

So how do I specify that the ClassPersister for Inner1 is same as that for Inner?

For retrieval, I would use a method Outer.setInner1(Inner i) which can construct an Inner1 from the passed parameter.

Thanks in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 07, 2005 2:31 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
Code:
<class name="Inner">
   ...
   ...
     <subclass name="Inner1"/>
</class>


It cannot be the exact same persister because there is one crucial difference - the classname ;) (which is used as discriminator to be able to distinguish between data that is Inner or actually Inner1)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 07, 2005 11:27 am 
Newbie

Joined: Wed Jul 07, 2004 11:15 pm
Posts: 6
Location: California, USA
max wrote:
<subclass name="Inner1"/>....It cannot be the exact same persister because there is one crucial difference - the classname ;) (which is used as discriminator to be able to distinguish between data that is Inner or actually Inner1)

Thanks, max. But this seems to require a discriminator. Unfortunately I do not know the value of the discriminator column statically; table Inner has a column Type that is foreign key into the the "type" table.

When I did use the persister for the superclass the object was saved correctly. Am I missing something? I do not want Hibernate to determine the correct type of the object during retrieval and instead treat it as an object of the superclass Inner itself.

Thanks in advance for your help. I am hoping I will be able to do this without having to repeat the specification for all the subclasses.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 07, 2005 12:27 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
what kind of object model do you have since the class doesn't matter to you when it is retreived ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 07, 2005 3:29 pm 
Newbie

Joined: Wed Jul 07, 2004 11:15 pm
Posts: 6
Location: California, USA
max wrote:
what kind of object model do you have since the class doesn't matter to you when it is retreived ?

Well the class does matter upon retrieval, but I plan to do that by hand:

Code:
class Outer{
  Inner1 inner1;

   /* for use by Application */
  Inner1 getInner1() { return inner1; }
  void setInner1(Inner1 inner1) { this.inner1 = inner1; }
 
  /* for use by Hibernate: */
  Inner getInner1AsInner() { return inner1; }
  void setInner1AsInner(Inner innner) { inner1 = Inner1.fromInner(inner); }
}


<hibernate-mapping>
  <class name="Inner">.....</class>
  <class name="Outer">
    <many-to-one name="inner1AsInner" column="inner1_id"
        class="Inner"/>
  </class>
</hibernate-mapping>


Does this make sense or am I trying something very stupid?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 07, 2005 3:34 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
sorry - can't see how you would do that in a safe manner - how would you ensure integrity for assocations to those objects ? The original object hibernate has recevied won't be updated when you change the "derived" one you create!

Seriously you need the discriminator ... how do *you* decide which Outer that get's to be an inner ?

If you have some magic for that why don't you just do the conversion from Inner to Outer when you need to save ? (note: this is said very ironically because it will be equally bad integrity-wise)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 07, 2005 3:51 pm 
Newbie

Joined: Wed Jul 07, 2004 11:15 pm
Posts: 6
Location: California, USA
max wrote:
sorry - can't see how you would do that in a safe manner - how would you ensure integrity for assocations to those objects ? The original object hibernate has recevied won't be updated when you change the "derived" one you create!

Seriously you need the discriminator ... how do *you* decide which Outer that get's to be an inner ?

If you have some magic for that why don't you just do the conversion from Inner to Outer when you need to save ? (note: this is said very ironically because it will be equally bad integrity-wise)


Let me first thank you for the continued promptness of your responses. I know it is easy to loose interest, especially from all accounts I am not doing the "right thing".

I am afraid I might have confused you with the terms. The Outer is always Outer. There are several Inner* types, which all extend Inner. For these Inner* types, only the fieds that are inherited from the superclass Inner need to be persisted.

Actually the conversion that you ironically refer to is the very approach I have been considering: in method getInner1AsInner construct an Inner and return it (to Hibernate) for persisting and during retrieval when Hibernate calls setInner1AsInner construct an Inner1 from the passed parameter and assign it to the field.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 08, 2005 3:53 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
the terms on which class comes from where does not matter in this case.

You will have a heck of a time keeping the object graphs in sync.

e.g.

A1->B2 (where B actually is an A)

Save it to hibernate as (A1->A2, but A2 is not B2, it's a new instance - changes to B2 will not be visible on A2 and vice versa)

Loading it from hibernate you get A1->A2, but you "convert" A2 to a B2, but do you remember to make A1 point to B2 also ? and what if there are more references ? ....you are doing something that will mess you up! ;)

If there really is a difference between these objects (there are since you have different classes and i guess methods or implementations for them - then that should be persisted together with them - namely a discriminator.

_________________
Max
Don't forget to rate


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