-->
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.  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: One to many question
PostPosted: Mon Dec 18, 2006 11:19 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
Hi. I'm new to hibernate..

I need a little help about an association mapping.

Take a simple scenario:

user <many-to-one> level
ID......................................ID
Name.................................Name
LevelID

I need to get level name of a user, but I'm not sure what is the best way.

Currently what I am using:

User POJO / Mapping
Code:
private Integer id;
private String name;
private Integer levelid;
private Level level; // extra class to get level name

Code:
<class name="User" table="User" catalog="test">
   <id name="id" type="java.lang.Integer">
      <column name="ID" />
      <generator class="increment" />
   </id>
   <property name="name" type="java.lang.String">
      <column name="Name" />
   </property>
   <property name="levelId" type="java.lang.Integer">
      <column name="LevelID" />
   </property>
   <many-to-one name="level" class="Level"   column="LevelID" insert="false" update="false" unique="false" />
</class>


Level POJO
Code:
private Integer id;
private String name;


Code:
<class name="Level" table="Level" catalog="test">
   <id name="id" type="java.lang.Integer">
      <column name="ID" />
   <generator class="increment" />
   </id>
   <property name="name" type="java.lang.String">
      <column name="Name" />
   </property>
</class>


When I got a user object loaded from DB, I can get it's LevelName by user.level.getName(), which causes 2 select queries:

Code:
select ... from User ...  >> only once
select ... from Level where ID= ... >> per different Level ID



I can do it in pure sql by one query:

Code:
Select User.ID, User.Name, Level.Name From User, Level Where Level.Id = User.LevelID


Question updated:
pease see http://forum.hibernate.org/viewtopic.ph ... 01#2335001


thanks.


Last edited by GBerberoglu on Wed Dec 27, 2006 5:27 am, edited 4 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 4:06 pm 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
http://www.hibernate.org/hib_docs/v3/re ... e-fetching


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 6:27 pm 
Beginner
Beginner

Joined: Tue Aug 29, 2006 8:13 pm
Posts: 32
Location: Spain (GU)
I would try to change the lazy load. You had better to test with lazy=false.

Maybe this runs!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 3:24 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
Nope still cant do it..

Code:
<many-to-one name="level" class="Level"   column="LevelID" insert="false" update="false" unique="false" lazy="true" fetch="join"/>


that uses 2 select per row..

there is no difference between fetch="join" and fetch="select" .. isn't that strange ?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 9:33 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
Suppose that Level class is so complex.. To get only name loading entire Level class in User does not make sense..

So, I must update User class like:

User POJO / Mapping

Code:
private Integer id;
private String name;
private Integer levelid;
// level class is so complex to load just for "name"
// private Level level;
private string levelName;

what will be the mapping then to get levelName?

I just need sth like that :

Select User.Name, User.LevelID, Level.Name From User, Level Where Level.ID = User.LevelID


Last edited by GBerberoglu on Fri Dec 22, 2006 4:56 am, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 2:38 pm 
Beginner
Beginner

Joined: Tue Aug 29, 2006 8:13 pm
Posts: 32
Location: Spain (GU)
Have you ever tested with a query in Native SQL), something like that:
http://www.hibernate.org/hib_docs/refer ... rysql.html


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 22, 2006 4:41 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
Javier Martinez wrote:
Have you ever tested with a query in Native SQL), something like that:
http://www.hibernate.org/hib_docs/refer ... rysql.html


nope, I dont know how to use query result without casting it to a class..


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 22, 2006 5:22 am 
Regular
Regular

Joined: Thu Aug 17, 2006 4:50 am
Posts: 55
Location: Mallorca
have you tried:

Quote:
from User user
join fetch user.level
where (... where clause ...)


?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 22, 2006 5:43 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
dominicus wrote:
from User user
join fetch user.level
where (... where clause ...)


can you help me a little more:

What will be where clause and level property in user.hbm.xml ?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 22, 2006 5:50 am 
Regular
Regular

Joined: Thu Aug 17, 2006 4:50 am
Posts: 55
Location: Mallorca
level property, as far i understand your problem, is ok.

only revise the attributes:
insert="false" update="false"

are you sure you want not to use this property when inserting /updating a user?

the where clause depends on witch users you want to load.

If you want to loads all the users then the select is:

Code:
from User user
join fetch user.level


if you want to retrieve just one user by id then

Code:
from User user
join fetch user.level
where user.id = ?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 22, 2006 6:15 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
thanks for your interest, I'll explain my problem in one post:

Tables;
user <many-to-one> level
ID....................................ID
Name...............................Name
LevelID

To reach User's level name, I create a Level class inside User class and map it using <many-to-one> (see my first post)

But now, I found loading entire Level class just to get Level.Name is not efficient. So instead of using Level class in User, I want to use a String property named "levelName" and map it another table's field.

is that possible ? mapping a property to another table's field without association ?

User.levelName<String>

User POJO / Mapping
Code:
private Integer id;
private String name;
private Integer levelid;
// level class is so complex to load just for "name"
// private Level level;
private string levelName;

Code:
<class name="User" table="User" catalog="test">
   <id name="id" type="java.lang.Integer">
      <column name="ID" />
   <generator class="increment" />
   </id>
   <property name="name" type="java.lang.String">
      <column name="Name" />
   </property>
   <property name="levelId" type="java.lang.Integer">
      <column name="LevelID" />
   </property>
   <property name="levelName" type="java.lang.Integer" insert="false" update="false" >
      >>>>> what will be here ? <<<<<
   <!-- this property mapped to another table's column: Level.Name where Level.ID = User.LevelID -->
   </property>
</class>


Last edited by GBerberoglu on Wed Dec 27, 2006 5:35 am, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 22, 2006 6:38 am 
Regular
Regular

Joined: Thu Aug 17, 2006 4:50 am
Posts: 55
Location: Mallorca
I think that if the load of user and corresponding levels is done with a unique select, the performance will be quite acceptable.

IMO, it does not pay to "corrupt" your domain model just for this case.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 27, 2006 5:31 am 
Newbie

Joined: Thu Dec 07, 2006 9:48 am
Posts: 18
any more ideas ?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 28, 2006 6:40 pm 
Regular
Regular

Joined: Thu Aug 17, 2006 4:50 am
Posts: 55
Location: Mallorca
If you are worried about the overhead of creating an extra Level object, you can create your DTOs with the exact number of fieds you want to return and use HQL to return these types.

Here is an example from the documentation:

Code:
select new Family(mother, mate, offspr)
from DomesticCat as mother
    join mother.mate as mate
    left join mother.kittens as offspr


you can find the example and explanation here:

http://www.hibernate.org/hib_docs/v3/reference/en/html/queryhql.html#queryhql-select

In your case, the DTO will be probably the User class definitius plus a String field for the level name.

Note you have to provide a constructor exactly as is invoked in the select clause of the HQL.

Hope this helps !


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 29, 2006 12:25 am 
Newbie

Joined: Sun Dec 24, 2006 10:24 pm
Posts: 5
Probably you can take a look at this:

http://www.hibernate.org/hib_docs/v3/re ... oc-complex

<join> maybe is what you need


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next

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.