views:

414

answers:

3

I have read some post about fetch=join - http://nhforge.org/blogs/nhibernate/archive/2009/04/09/nhibernate-mapping-lt-many-to-one-gt.aspx (ser4ik.livejournal.com/2505.html) So I have some question, Forexample I have class

<class name="AttributesInf" table="attr_inf">      
 <id name="Id">
   <generator class="identity"/>
 </id>
 <property name="Name" />
    <property name="Desc"/>
</class>

and

<class name="AttributeValue" table="attr_val">      
 <id name="Id">
   <generator class="identity"/>
 </id>
 <property name="Value" />
 <many-to-one name="AttrName" column="attrId"/>
</class>

If I use this mapping without set fetch="join" I get sql:

Select av.Id, av.Value, av.attrId From attr_val av where av.Id=...()

and after then separate sql queries like:

Select * From attr_inf where Id = av.attrId

So my Result Is:

class AttrinuteInf 
{ 
int Id; 
string Name; 
string Desc; 
} 
class AttributeValue 
{ 
int Id; 
string  Value; 
AttributeInf AttrName;
}

If I set fetch="join" then I get one query:

Select u.Id, u.UserName, u.BlogId, b.Id, b.BlogName, b.BlogAuthor, b.BlogMsg 
from Users u
Left outer join Blogs b 
On u.BlogId=b.Id
Where u.Id = ...

So I expect to get one Class:

class AttributeValue
{
int Id;
string  Value;
string Name;
string Desc;
}

But I have the same result as if I not set fetch to "join".

Is this all right? Are there any way to get properties from class maped as <many-to-one> directly? (not as AttrName.Name, but simply Name )

Explanation:

Part of mapping set above don't show my real problem. I want to map some entity as IDictionary<string,AttributeValue>. I map it as

<map name="Attributes" table="attr_val" lazy="true" cascade="all-delete-orphan" inverse="true">
<key column="item_id"></key>
<index column="name"></index> //I don't have that item in class AttributeValue, that is why I try to get it from other table
<one-to-many class="AttributeValue"/>
</map>
A: 

It's not the way you describe it. Your entities do not change depending on what you request.

You will obtain a list of instances of your main entity, with the association to the other being fetched. So if, in your code, you access the association, you will find the values.

If you don't fetch it, you wouldn't be able to access those fields, as they would not have been retrieved from the database.

KLE
I understand, thank you. But then what I can do?
Kate
I know that your mappings are not correct for regular Hibernate, I'm not sure for NHibernate. I don't see your association... Sorry, I don't have an environment to test that right now, to help you :-(
KLE
+1  A: 

I don't understand your question. The 'fetch-join' attribute just defines how the sql that NHibernate generates to retrieve instances of your classes, should look like. It has nothing to do with 'what' will be returned. NHibernate will translate the recordset (that is the result of the query) to correct instances of your classes.

If you just want to retrieve parts of your entity (like the name for instance), then you'll have to write a HQL query, or use the ICriteria API and maybe use projections.

Frederik Gheysels
Where do you offer to use HQL? in mapping?I want fix this item only by mapping, that is why ICriteria API and projections aren't suit.
Kate
Then, you'll have to create new class, which only contains the properties you're interested in, and map this class to the table(s).But, I would not recommend this approach. Why is using hql or icriteria not an option ?
Frederik Gheysels
I edit post above to explain.
Kate
+5  A: 

This isn't doing what you think it's doing. Using fetch=join is just there to eager load the many side of the relationship. In both cases you end up with the same objects returned. By default NHibernate will lazy load the related entities (which is why you get the second query). By using fetch=join you are asking for the entire object relationship at once but it will still populate the objects the same as without the fetch=join.

Michael Gattuso