-->
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: NHibernate bag problem
PostPosted: Wed Nov 29, 2006 5:34 am 
Beginner
Beginner

Joined: Wed Nov 22, 2006 5:59 am
Posts: 29
Location: London
Hibernate version: 1.2.o Beta 1

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"
namespace="FIXMESSAGE" assembly="FIXMESSAGE" >
<class name="MessageX">
<id name ="MessageId">
<column name="MessageId" sql-type="int" />
<generator class="native" />
</id>
<bag name="Destinations" cascade="all" fetch="select" lazy="true" inverse="true">
<key column="MessageId" foreign-key="fk_destination_message" />
<one-to-many class="Destination" />
</bag>
</class>
</hibernate-mapping>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"
namespace="FIXMESSAGE" assembly="FIXMESSAGE">
<class name="Destination">
<id name ="DestinationId" column="DestinationId" type="int">
<generator class="native" />
</id>
<property name="Address" type="string"/>
<many-to-one name="MessageId" class="MessageX" column="MessageId" foreign-key="fk_destination_message" fetch="join" />
</class>
</hibernate-mapping>


Code:

public void testConnection()
        {
            try
            {
                ISessionFactory factory = new Configuration().Configure().BuildSessionFactory();
                ISession session = factory.OpenSession();
                MessageX m = new MessageX();
                m.AddDestination(new Destination());
                m.AddDestination(new Destination());
                session.Save(m);
                MessageX ms = session.Get<MessageX>(1);
                IQuery query = session.CreateQuery("from MessageX message inner join fetch message.Destinations");
                IList<MessageX> result = query.List<MessageX>();
                session.Close();
            }
            catch (Exception e)
            {

            }
        }


I have a problem with Nhibernate. When I use the above mapping to create a very simple one to many relationship the database and tables etc are created fine and the proper relationships mapped etc. I can then insert data into the tables and its inserted in the correct way. If I then use lazy loading to select the data this works fine. The problem I'm having is that if I use an HQL query to join the two tables, instead of getting one MessageX which has two destination child objects I get two identical MessageX which each have two Destination child objects. This changes depending on how many Destination objects a message object refers to e.g if I added 3 Destination child objects to the MessageX I'd get 3 copies when I queried.

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 29, 2006 11:32 am 
Beginner
Beginner

Joined: Tue Nov 21, 2006 5:18 am
Posts: 31
Location: Bangalore, India
Hi,

You can only use this query "from MessageX message"

this will return MessageX object, and you can iterate through list and get all child objects, its like lazy loading.

Otherwise you have to use like

session.CreateQuery("select message.messageId, d.destinationId, d.address from MessageX message inner join fetch message.Destinations d");
this above will return two rows.

_________________
persist_coder
--credit please if it helps you


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 29, 2006 12:42 pm 
Beginner
Beginner

Joined: Wed Nov 22, 2006 5:59 am
Posts: 29
Location: London
This is not what I am after. These two tables are part of a much larger schema I just extracted them for debugging purposes. The schema uses lazy loading by default for performance issues. I want to be able to load up the data I need using a join because the way sessions are implemented in the system means that by the time I want to use Destinations the session is already closed and therefore I get an Exception. The query you gave returns two objects where as I need the one Message object with the two Destination objects as part of its Destinations collection.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 29, 2006 3:22 pm 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
This is considered a feature of NH, not a bug. To resolve this you can add your results to a set, and this will eliminiate the duplicates.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 30, 2006 4:49 am 
Beginner
Beginner

Joined: Wed Nov 22, 2006 5:59 am
Posts: 29
Location: London
There is someone else on a different project who gets the result I want from the same query. I don't see why anyone would want a copy of the same object with the same children. What if my Message object had 1000 children I wouldn't want 1000 copies of the object every time I wanted to do a join on it. I have another problem when I try to use a <list> to keep the list ordered. When I insert Objects no value is inserted into the index column so I get an error when I try to query it. The exact same code I am using for this works for someone else who is doing the same thing on a different project.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 30, 2006 10:24 am 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
Well, if you think about it, when you select a parent/child relationship with one SQL statement, you are going to get redundant data. That's just the way it is. You either have to remove the redundant data or you have to use more than one SQL statement. Since NH isn't going to assume anything it's going to let you remove the redundant objects.

In your case you can use a criteria query (in which case the fetch="select" will direct NH to generate n+1 selects... you should probably change that to fetch="subselect" which will generate just 2 selects), or you can remove the redundant objects yourself as already discussed above.

I'm not sure why someone else wouldn't experience the same behavior you have.

As to your second problem, you said that nothing is inserted into the index column. That is correct since you are using a bag. To get an ordered list you must use a <list...> tag or use the <set...> tag to get an ordered set.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 30, 2006 10:47 am 
Beginner
Beginner

Joined: Wed Nov 22, 2006 5:59 am
Posts: 29
Location: London
Thanks for your reply. In regards to the index not being populated problem. I was using a <list> instead of a bag I just changed it to bag as I couldn't get list to work because of the indexing problem.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 30, 2006 2:22 pm 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
Another point to note here is that although you appear to get duplicate objects in the collection you are, in fact, getting duplicate references to the same object...which means there isn't too much wasted memory.

Symon.


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.