-->
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.  [ 12 posts ] 
Author Message
 Post subject: A problem with inheritance
PostPosted: Sun May 30, 2004 11:09 pm 
Beginner
Beginner

Joined: Mon May 17, 2004 7:15 am
Posts: 24
Hi,

I am trying to figure out how to access the inheritance hierarchy within Hibernate, but still got errors when I tried to create a new instance of the child class with the existing instance of the parent class.

My mapping file is:


<hibernate-mapping>
<class
name="com.qusiness.test.A"
dynamic-update="false"
dynamic-insert="false"
>

<id
name="id"
column="class_id"
type="java.lang.Long"
>
<generator class="hilo">
</generator>
</id>

<property
name="password"
type="java.lang.String"
update="true"
insert="true"
column="password"
/>

<joined-subclass
name="com.qusiness.test.B"
dynamic-update="true"
dynamic-insert="true"
lazy="true"
>
<key
column="class_id"
/>
<property
name="BProperty"
type="java.lang.String"
update="true"
insert="true"
column="BProperty"
/>
</joined-subclass>
</class>

</hibernate-mapping>


and the code is :

A a = (A)s.load(A.class, new Long(1));
B b = new B();
b.setId(a.getId());
b.setPassword(a.getPassword());
b.setBProperty("b property");
s.save(b, a.getId());


the error is :

net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 1, of class: com.qusiness.test.B
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:834)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:804)
at com.qusiness.test.HiberTest.createBwithA(HiberTest.java:63)
at com.qusiness.test.HiberTest.main(HiberTest.java:101)


I think Hibernate should be powerful enought to process my case. Expect your replies.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 31, 2004 12:38 am 
Newbie

Joined: Mon Apr 05, 2004 3:48 am
Posts: 8
please show child mapping file.

In fact, you can debug it according to the error hint.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 13, 2004 3:24 am 
Beginner
Beginner

Joined: Mon May 17, 2004 7:15 am
Posts: 24
nesta wrote:
please show child mapping file.

In fact, you can debug it according to the error hint.


Thanks for your post.

Two map files were put into a single file, as listed as previous.


I think this is a problem that Hibernate developers frequently meet, as well as a general usage of the inheritance.


My problem can be abstracted as:
[b][i]Creates a new instance of class B which inherits from class A with an existing instance of A. For an exmaple, there are two classes Person and Customer inheriting from Person. The business logic is that a customer is created when a person buys products in the system. In the implementation, the instance of Person has alreay existed and a new instance customer is going to be created with the existing instance of Person.

So, how can I use Hibernate to process this case?

[/i/[b]


I will be really grateful if someone has any ideas about this.

Best wishes,

James


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 13, 2004 2:57 pm 
Beginner
Beginner

Joined: Mon Sep 29, 2003 10:32 pm
Posts: 35
Location: Toronto, Ontario
The semantics used by Hibernate is quite correct. Within the session there should be only one unique instance of an entity. You are a Person and you're are also a Customer but there's still only one instance of you at any time.

So the solution would be to ensure that the Hibernate session only sees one instance at any time.

a. Retrieve the Person using a query, then copy the properties to the newly created Customer object then save.
OR
b. Load the Person, close the session, create a Customer using the person properties or with a method on the Person class

Customer becomeCustomer();

then when the user seeks to become a Customer open a session and save.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 13, 2004 10:12 pm 
Beginner
Beginner

Joined: Mon May 17, 2004 7:15 am
Posts: 24
javamona wrote:
The semantics used by Hibernate is quite correct. Within the session there should be only one unique instance of an entity. You are a Person and you're are also a Customer but there's still only one instance of you at any time.

So the solution would be to ensure that the Hibernate session only sees one instance at any time.

a. Retrieve the Person using a query, then copy the properties to the newly created Customer object then save.
OR
b. Load the Person, close the session, create a Customer using the person properties or with a method on the Person class

Customer becomeCustomer();

then when the user seeks to become a Customer open a session and save.


Thank you very much. I tried solutions that you mentioned above and still got problems. Let's overview the actions perfomed by Hibernate when creating a new instance of a child class: Hibernate inserts all property values inherited from the parent class into the parent class table and then inserts other property values owned by the child classs into the child class table.

That means if we copy properties of an EXISTING Person object to a new Customer object in a suitable way (e.g. close the session and create) and successfully create the Costomer object with the EXISTING Person object, a duplicated Person object will also be created. I've tried the above solutions and the problem did happen.

I am completed confused about this and doubting the sematics used by Hibernate is accurate enough.

Welcome any suggetions. Thanks.

Cheers,

James


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 14, 2004 5:01 am 
Beginner
Beginner

Joined: Mon May 17, 2004 7:15 am
Posts: 24
Does anybody else have any ideas about this problem?

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 14, 2004 9:47 am 
Beginner
Beginner

Joined: Mon Sep 29, 2003 10:32 pm
Posts: 35
Location: Toronto, Ontario
I apologize for not having thought it all the way through. Here's my 3rd cent:
c. Refactor the inheritance heirarchy to a composition relationsship. So instead of Customer IS-A Person, then a Person HAS-A CustomerInfo. Map this as a one-to-one relationship. Create the CustomerInfo class and associate it with the Person when a Person becomes a Customer.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 14, 2004 11:18 am 
Beginner
Beginner

Joined: Mon May 17, 2004 7:15 am
Posts: 24
Thank you very much.

Solution C should work well, but I have to break the OO model. Anyway, I am really grateful for your quick and useful replies.

What I am trying to do is to change the action of the service insert(..) provided by the class NormalisedEntityPersister. It is not a good way to work with the open source. But this will keep my OO model consistent in the whole development process. Acturally, it is also the greatest advantage that Hibernate brings to my project.

If this project succeeds, I will tell the story to the Hibernate team so that the guy in the team who said Hibernate users would not like to tell their successful stories will not be such angry with us. A open source project was successfully borned because of geniuses, and grows up with its user community.

Aha, I should get back to our topic. Do you think the problem dissussed here is a general case and should be supported directly by
Hibernate?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 14, 2004 11:51 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
The problem you face is that Hibernate is too strict with OO.
In java, there is no way to change the same instance from ParentClass to ChildClass. You have to copy the appropriate values. This is the same for Hibernate.
That's why i'm thinking your domain model does not manage Person-Customer link properly, since a person can mute into a Customer during it's life time

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 14, 2004 10:35 pm 
Beginner
Beginner

Joined: Mon May 17, 2004 7:15 am
Posts: 24
emmanuel wrote:
The problem you face is that Hibernate is too strict with OO.
In java, there is no way to change the same instance from ParentClass to ChildClass. You have to copy the appropriate values. This is the same for Hibernate.
That's why i'm thinking your domain model does not manage Person-Customer link properly, since a person can mute into a Customer during it's life time



In Java, a new instance of the parent class is not created when you create a new subclass instance and copy property values of an existing instance of the parent class, is it?

I think Hibernate as a tool in the persistent layer should be capable of dealing with this case, which is a considerablely general in the real life.

Cheers

James.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 21, 2004 3:08 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
jamstang wrote:
In Java, a new instance of the parent class is not created when you create a new subclass instance and copy property values of an existing instance of the parent class, is it?

No, neither in Hibernate. In Java the parent instance IS the subclass instance, do does Hibernate.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 22, 2004 11:13 pm 
Senior
Senior

Joined: Sun Oct 26, 2003 5:05 am
Posts: 139
Yeah, this sounds like the person should have a customerinfo object and you can allow it to be null.


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