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.  [ 6 posts ] 
Author Message
 Post subject: Join fetching a map and all/some contained elements
PostPosted: Wed Aug 13, 2008 5:42 am 
Regular
Regular

Joined: Tue Jul 29, 2008 3:30 am
Posts: 74
I can't figure out how to join fetch a map and all/some contained elements so that NHibernate won't need additional select statements when I access the map.

Example:
Entity "LocalizationElement" contains a map "LocalizationsDictionary" which is a IDictionary<int, string> where key and value are from the table "Localization" in my database.
Now I want to join fetch that map so that no additional select statements are needed if I get an element from that map.

Could someone please give me the correct HQL for that?

Hibernate version:
1.2.1.GA

Mapping documents:
LocalizationElement:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Name.Library" namespace="Name.Library.BOs">
    <class name="LocalizationElement">
        <id name="ID">
            <generator class="identity"/>
        </id>
        <map name="LocalizationsDictionary" table="Localization" inverse="true">
            <key column="LocalizationElementID"/>
            <index column="LanguageID" type="Int32"/>
            <element column="Text" type="String"/>
        </map>
    </class>
</hibernate-mapping>

Localization:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Name.Library" namespace="Name.Library.BOs">
    <class name="Localization">
        <composite-id>
            <key-many-to-one name="LocalizationElement" column="LocalizationElementID"/>
            <key-many-to-one name="Language" column="LanguageID"/>
        </composite-id>
        <property name="Text"/>
    </class>
</hibernate-mapping>


Last edited by cremor on Thu Aug 14, 2008 3:03 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 14, 2008 3:02 am 
Regular
Regular

Joined: Tue Jul 29, 2008 3:30 am
Posts: 74
Ok, forget about fetching all elements from the map. I tried it again and it works just like I've expected with "join fetch LocalizationsDictionary". Don't know why that didn't work yesterday...

But there is still the question how to fetch only some of the elements in the map.

There seems to be a question first: Is it even possible with NHibernate to only load the requested items (with dictionary[key]) without fetching the whole map?
Currently I'm only calling ContainsKey() and the indexer of my dictionary, but that fetches the whole dictionary from the database. Is this the expected behaviour or is it also possible for NHibernate to just fetch the requested items in the map?

If it's possible to just fetch the requested items, how should I modify my query so these items (I know them at the point where I execute the query) are fetched right with the query?

Code:
from TemplateType tt
join fetch tt.NameLocalizationElement le
join fetch le.LocalizationsDictionary

(NameLocalizationElement is just a many-to-one reference to LocalizationElement, so I haven't posted the mapping of that class here).

Thanks in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 14, 2008 5:22 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
I haven't tried what you want to do, yet, but here is an example from the docs that goes into that direction:

Code:
select person from Person person, Calendar calendar
where calendar.Holidays['national day'] = person.BirthDay
    and person.Nationality.Calendar = calendar

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 14, 2008 9:01 am 
Regular
Regular

Joined: Tue Jul 29, 2008 3:30 am
Posts: 74
Thanks for your reply, but either I can't apply that correctly to my mappings or it's the wrong approach.

I'll try to clearify what I need:
I have a entity LocalizationElement which has a map (IDictionary<int, string>) of Localizations. Now I know that I'll access a single Localization in this map with the given LanguageID like the following line shows:
Code:
return localizationElement.LocalizationsDictionary[languageID];

This line of code results in no additional select statements if I join fetch the whole map in my HQL query. But because I only need this one element in the dictionary all other elements which are loaded too are wasted performance.

If I don't join fetch the map in my HQL query a additional SQL statement is executed which loads all Localizations into the map. So again all other elements are wasted performance.

It would be great if I could access a element in the dictionary without the need to load all other elements from the database. And that one element should be fetched in my initial HQL query so no additional SQL statement is needed when I access it.

So that's the question: Is it possible to configure NHibernate so it doesn't load the whole map if I access a specific element in the map?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 14, 2008 9:59 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
I don't think so. For some kind of associations there's the possibility of setting lazy to "proxy" but I don't think that's possible for collections.

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 14, 2008 10:25 am 
Regular
Regular

Joined: Tue Jul 29, 2008 3:30 am
Posts: 74
Yes, seems like it's not possible, I get the following exception:
Code:
XML validation error: The 'lazy' attribute has an invalid value according to its data type.


So it seems like I have to fetch the whole map :-(

Nevertheless: Thanks for your replies!


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