-->
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: Help with Composite-id and parent/child relationship
PostPosted: Fri Aug 05, 2005 6:10 am 
Newbie

Joined: Fri Aug 05, 2005 4:32 am
Posts: 5
Hi,

I am new to hibernate. Checked the references and tutorials but not able to find a solution for my problem. I am unable to insert records in Parent and child relation tables at a time.

I have the following tables.

Table: Protocol

protocol_id number; ( primary key )

protocol_name varchar2(50);


Table: Protocol_properties

protocol_id number;
property_id number;
property_value varchar2(50);

primary key(protocol_id, property_id)
where protocol_id is foriegn key referencing protocol_id of Protocol table.

I have the beans for both the tables with get and set methods.
public class Protocol{
int protocolId;
int protocolName;
ProtocolProperties[] properties;
/* get/ set methods for all these properties */

}

public class ProtocolProperties{
int protocolId;
int propertyId;
String propertyValue;
/* get/set methods for these properties */
}

now if i get a Protocol Object with all the properties in the array, i would like to save them to the above mentioned tables.
So, specified the following entries in my hibernate mapping xml:

<class name="Protocol" table="Protocol">
<id name="protocolId" column="PROTOCOL_ID">
<generator class="increment"/>
</id>
<property name="protocolName" column="PROTOCOL_NAME"/>

<array name="properties" table="Protocol_Properties">
<key column="PROTOCOL_ID" not-null="true"/>
<list-index column="PROPERTY_ID" /> <!-- not sure what is this for?-->
<one-to-many class="ProtocolProperties"/>
</array>
</class>
<class name="ProtocolProperties" table="Protocol_Properties">
<composite-id>
<key-property name="propertyId" column="PROPERTY_ID"/>
<key-property name="protocolId" column="PROTOCOL_ID"/>
</composite-id>
<property name="propertyValue" column="PROPERTY_VALUE"/>
</class>

I am getting duplicate mapping error for protocolId, so i also tried with key-many-to-one property for protocolId in composite-id like
<key-many-to-one name="protocolId" class="Protocol" table="Protocol"/>

but no luck, getting the same error. Could anyone please let me know how to specify the referenced protocolId correctly in the "ProtocolProperties" class.

Note: The protocolId in Protocol is generated by system and it should use the same protocolId for all the properties in Protocol_Properties table as well, without me updating that property explicitly to each of the ProtocolProperites objects.[quote][/quote]

_________________
With Regards,
Ravi


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 05, 2005 6:32 am 
Expert
Expert

Joined: Thu May 26, 2005 9:19 am
Posts: 262
Location: Oak Creek, WI
Hi

Why are you are confusing a lot!!!!!!

why do u need a String array for Properties? Instead you could use a ArrayList.

Check this one

<class name="Protocol" table="Protocol">
<id name="protocolId" column="PROTOCOL_ID">
<generator class="increment"/>
</id>
<property name="protocolName" column="PROTOCOL_NAME"/>
<bag name="properties" inverse="true">
<key column="PROTOCOL_ID"/>
<one-to-many class="ProtocolProperties"/>
</bag>
</class>

<class name="ProtocolProperties" table="Protocol_Properties">
<composite-id>
<key-property name="propertyId" column="PROPERTY_ID"/>
<key-many-to-one name="properties" class="ProtocolProperties" column="PROTOCOL_ID" not-null="true"/>
</composite-id>
<property name="propertyValue" column="PROPERTY_VALUE"/>
</class>

Where i point properties refers to the ArrayList. I have put the key-many-to-one to prevent values from duplicating.

You can use bag or set or map each has its own funcationlity.

By using this above
1) you can add all the child object to the ArrayList of the Parent.
2)Save the Parent.

All your child would be saved in the table according

_________________
RamnathN
Senior Software Engineer
http://www.linkedin.com/in/ramnathn
Don't forget to rate.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 05, 2005 7:17 am 
Newbie

Joined: Fri Aug 05, 2005 4:32 am
Posts: 5
Hi Ramnath,
I tried your suggestion of using collection. I used list.

Now though its not throwing any exceptions, it is not inserting records in my child table. But inserted a row in parent table. What may be the cause for it?

_________________
With Regards,
Ravi


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 05, 2005 10:42 am 
Beginner
Beginner

Joined: Thu Mar 31, 2005 9:58 pm
Posts: 25
Location: Valparaiso
try cascade=CascadeType.ALL in the collection on the parent side

_________________
Daniel Casanueva R.

Jcode
Valparaiso, Chile


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 08, 2005 2:58 am 
Newbie

Joined: Fri Aug 05, 2005 4:32 am
Posts: 5
Hi Daniel,

Thx for the info. It is working if the application provides the "protocolId" for parent table as well as the child table.

What if the primary key of Protocol table i.e protocolId is system generated using <generator class="increment"/> and used as part of composite key in child table "Protocol_Properties" like

<composite-id>
<key-property name="propertyId" column="PROPERTY_ID"/>
<key-property name="protocolId" column="PROTOCOL_ID"/>
</composite-id>

As i won't be knowing wht the id will be generated for the parent table i can't give the value for the "protocolId" property in my child bean.

I am getting parent key not found exception because of this issue.

Pls let me how to inform hibernate that it should take the newly generated id of the "protocolId" attribute of parent table for the "protocolId" attribute of the child table as well.

_________________
With Regards,
Ravi


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 08, 2005 1:35 pm 
Beginner
Beginner

Joined: Thu Mar 31, 2005 9:58 pm
Posts: 25
Location: Valparaiso
Mmmm i'm think you're not setting the parent to the child. In the Protocol class you may have something like this (if you "properties" field in the Protocol class is a Collection, if is a Object[] is different, but is the same idea):

public void addProtocolProperties(Object o) {
if (o == null) {
throw new IllegalArgumentException("NULL Argument");
}
if (o instanceof ProtocolProperties {
if (!properties.contains(o)) {
ProtocolProperties p = ProtocolProperties o;
p.setProtocol(this);
properties.add(p);
}
}
}


I hope this will help you,

_________________
Daniel Casanueva R.

Jcode
Valparaiso, Chile


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 09, 2005 2:10 am 
Newbie

Joined: Fri Aug 05, 2005 4:32 am
Posts: 5
Hi Daniel,

Thanks for replying back. As said in my first post, i have a one-to-many association from parent to child.

My Protocol bean is

public class Protocol{
int protocolId;
int protocolName;
ProtocolProperties[] properties;
/* trying with list also. To check whether object array is giving any prob*/
/* get/ set methods for all these properties */

}

and ProtocolProperties bean is

public class ProtocolProperties{
int protocolId;
int propertyId;
String propertyValue;
/* get/set methods for these properties */
}

I wont be having any reference to paret object in my ProtocolPropeties object other than the parent id i.e protocolId which is auto genereated for parent. So i cannot set any value for this property. Due to this it is trying to insert a child record with '0' as protocolId. As the parent table Protocol doesn't have any record with '0' as protocolId, getting "Parent key not found exception".

Need to get a way to inform hibernate to take the newly generated protocolId from Protocol class and assign it protocolId property in ProtocolProperties class.

Hope you got my problem. Let me know if you have any solution for this.

_________________
With Regards,
Ravi


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 09, 2005 12:38 pm 
Beginner
Beginner

Joined: Thu Mar 31, 2005 9:58 pm
Posts: 25
Location: Valparaiso
A child always must have a parent. I think you've 2 solutions:

1) Change the primary key and use a surrogate one and give the control to this new key to hibernate, in order to control the another key by yourself, because if you want to register a child without its parent always hibernate and the database will thrown errors and exceptions. This will be a lot of work, because you will have to "emulate" this parent-child control by yourself with HQL or SQL queries. I think this itn't clean.

2) Re-think your object model, because the thing you want to do broke some principles....


A question, your database is a pre-existing one?


Good luck with your problem

_________________
Daniel Casanueva R.

Jcode
Valparaiso, Chile


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.