-->
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: composite id with a field which is a foreign key
PostPosted: Fri Jun 08, 2007 11:31 am 
Newbie

Joined: Tue May 22, 2007 9:53 am
Posts: 9
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:

Mapping documents:

Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:

Name and version of the database you are using:

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Problems with Session and transaction handling?

Read this: http://hibernate.org/42.html


Hello, everybody! I've been using Hibernate with HSQLDB for some weeks and I have familiarized with the main features and have developed some simple applications to understand how to use it. Up to there, everything has been fine, I have achieved it relatively easy. But there is a problem I have found, during using Hibernate for the application I'm interested in. The thing is I have two entities like this

Entity{
composite-id "ID"
... (The rest of the fields)
}

ID{
"field 1"
"field 2" (foreign key, represents relationship between Entity and another entity)
}

How do I map this composite id? How do I map the foreign key called field 2? If all the fields in ID were foreign keys for Entity, how do I do these both things?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 02, 2007 5:13 pm 
Newbie

Joined: Tue May 22, 2007 9:53 am
Posts: 9
I've already found the way to do it. We must use <key-many-to-one> element inside the <composite-id> one. So if the entity looks like this:

Entity{
ID id (composite-id)
... (The rest of the fields)
}

ID{
Class1 "field 1"
Class2 "field 2" (foreign key, represents relationship between Entity and another entity)
}

where each "field" corresponds to a column in the table represented by the Entity. Then we must do this:

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="Entity" table="ENTITY">
<composite-id name="id" class="ID">
<key-many-to-one name="field1" column="COLUMN1" class="Class1"/>
<key-many-to-one name="field2" column="COLUMN2" class="Class2"/>
</composite-id>
... (The rest of the fields)
</class>
</hibernate-mapping>

These also works with all the fields in the composite id being foreign keys.


Top
 Profile  
 
 Post subject: loading
PostPosted: Wed Jul 18, 2007 8:52 am 
Newbie

Joined: Wed Jul 04, 2007 8:44 am
Posts: 5
Hi Alex,

I have the same situation as the one you describe, and defined the same type of mapping.

Now, I need to load my class which has a composite id using the id values only (I do not have the instances of the key part entities hydrated nor do I want to load them individually)

Could you (or anyone having the solution :) ) tell me how to write the Session.Load() client code for this case ?

Since the identifier class now has object references instead of values, I don't know what to pass as the second parameter to Load(type, id). If I try to create new instances of the referenced classes defining only the proper id, i get an exception about transient objects.

Could anyone tell me the proper way to load an object by id - not using HQL if possible - in the scenario ?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 20, 2007 3:04 pm 
Newbie

Joined: Tue May 22, 2007 9:53 am
Posts: 9
Hi RMartinon! If you have an Entity1 with a composite id which name is "z" (any kind of primitive datatype), let's suppose with a value "x" (any kind of primitive datatype) and an object which is your foreign key "entity2". This Entity2 must have an identifier I think, the most probably thing that could happen, is a value (any kind of primitive datatype) named "y". Something like this:

Entity1{
compositeID z;
... the rest of the attributes...
}

compositeID{
(primitive datatype) x;
Entity2 entity2;
}

Entity2{
(primitive datatype) y;
... the rest of the attributes...
}


Then if you want to retrieve the object from database without loading Entity2, you could do this:

1. Create a Query (org.hibernate.Query):

Query query=session.createQuery("from Entity1 entity1 where z.x=? and z.entity2.y=?").setXXX(1,xValue).setXXX(yValue); (where XXX depends on the primitive datatype we are dealing with)

2. Then obtain an iterator for the list of objects retrieved

Iterator it=query.list().iterator();

3. Search for the object

Entity1 entity1;
if(it.hasNext()){
entity1=(Entity1)it.next();
}

I use an "if" structure since I know the query will return only one object (Because I have defined in the "where" clause values for primary key). If there were more objects it would be replaced with "while" structure. If it is not found the object will be null. If you continue having problems continue asking. I hope this will be helpful!


Top
 Profile  
 
 Post subject: Criteria API
PostPosted: Mon Jul 23, 2007 3:10 am 
Newbie

Joined: Wed Jul 04, 2007 8:44 am
Posts: 5
Hi Alex,

Thank you for taking some time to reply.

Do you know the way to obtain the same results through the Criteria API ? Our team has decided that we wouldn't used HQL for our queries unless it can't be helped.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 25, 2007 9:59 am 
Newbie

Joined: Tue May 22, 2007 9:53 am
Posts: 9
I am not quite sure how exactlyit works, beacuse I haven't used it yet, but in Hibernate Reference Documentation, it is said this:

1.-To create a Criteria Query with conditions for searching

Criteria crit=session.createCriteria(Entity.class).add(Restrictions.idEq(key));
//key is the object representing the id

where Restrictions is a class with some methods to especify "Criterion" (Hiberante class that is used to set characteristics for that rows you want to be retrieved as objects). In this case I think the method idEq(Object value) is useful to set the id for the row you need, so I should retrieve only one object. There are many other methods for arithmetic comparisons, logical operations, etc. within Restrictions class, just as you could do with a "where" clause and, even for "order by clause" there is Order class and the method addOrder(Order order) in the Criteria class, and much more.
In summary, with the two lines you create the criteria to retrieve a row from DB as an object searching by its id, but there are a lot of things also that you can do with criteria as if you were working with SQL or HQL, just using classes from Hibernate packages, such as Restrictions, Order, etc.

2.-At last, to obtain the object is the same as with HQLQuery:

Iterator it=crit.list().iterator();

and you can proceed as we do with collections, just that I suppose there must be just one object within (for the case we are dealing with), so I would use if clause:

if(it.hasNext()){
Entity entity=(Entity)it.next();
}

Test it and let me know if it really worked. Good luck!


Top
 Profile  
 
 Post subject: Thanks
PostPosted: Wed Jul 25, 2007 10:14 am 
Newbie

Joined: Wed Jul 04, 2007 8:44 am
Posts: 5
Hi Alex,

Up till now i had been using Criteria.Add(Expression. ... ) and never looked into restrictions.

I'm going to dig in there and I'm sure your solution will do the trick.

Thanks for your help.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 01, 2008 1:40 pm 
Beginner
Beginner

Joined: Tue Jan 08, 2008 2:15 pm
Posts: 22
What is the equivalent of key-many-to-one with Hibernate annotations?


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.