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.  [ 11 posts ] 
Author Message
 Post subject: Criteria and one-to-many "could not resolve property&am
PostPosted: Thu Apr 10, 2008 5:05 am 
Newbie

Joined: Fri Feb 22, 2008 5:39 am
Posts: 14
Hello,

Sorry if the topic was already posted but I didn't find any help for my problem.
I have two entities "Piece" and "Ligne" and would like to query them with criteria API. As you can see in the following mapping files between "Piece" and "Ligne" there is a one-to-many relation.

I would like to get some "Piece" that IDPIECE = "anID" and "Lignes" that QTERESTEALIVRER property >0. When I query on the piece property IDPIECE = "anID" all works good but if I also query on "Ligne" property QTERESTEALIVRER, I have the following error "could not resolve property" there is no QTERESTEALIVRER property in the "Piece" class. How to tell NHIBERNATE that QTERESTEALIVRER is in "Ligne" class and that I want all pieces with IDPIECE="anID" with "Lignes" which QTERESTEALIVRER > 0 ? Why Criteria API doesn't make a link itself from mapping files? Here is the mapping files and some code.

Piece mapping :
Code:
<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="CommandesModel"
                   assembly="CommandesModel">

  <!-- Mappings for class 'ZPiece' -->
  <class name="Piece" table="ZPIECE" lazy="false">

    <!-- Identity mapping -->
    <id name="IDPIECE">
      <column name="ZP_IDPIECE" />
      <generator class="assigned" />
    </id>

    
     <version column="ZP_VERSION" name="VERSION" type="Int32" access="property" unsaved-value="0" generated="never" />
    
     <!-- One-to-many mapping: Lignes -->
     <bag name="Lignes" cascade="all-delete-orphan" lazy="false">
        <key column="ZL_IDPIECE" />
        <one-to-many class="Ligne" />
     </bag>
   
    <!-- Simple mappings -->
    <property name="NATUREPIECEG" column="ZP_NATUREPIECEG" />
    <property name="NUMERO" column="ZP_NUMERO" />
    <property name="SOUCHE" column="ZP_SOUCHE" />
    <property name="REFINTERNE" column="ZP_REFINTERNE" />
    <property name="REFEXTERNE" column="ZP_REFEXTERNE" />
    <property name="TIERS" column="ZP_TIERS" />
    <property name="TIERSLIVRE" column="ZP_TIERSLIVRE" />
    <property name="TIERSFACTURE" column="ZP_TIERSFACTURE" />
    <property name="REPRESENTANT" column="ZP_REPRESENTANT" />



  </class>
</hibernate-mapping>


Ligne mapping:
Code:
<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="CommandesModel"
                   assembly="CommandesModel">

  <!-- Mappings for class 'Ligne' -->
  <class name="Ligne" table="ZLIGNE" lazy="false">

    <!-- Identity mapping -->
    <id name="IDLIGNE">
      <column name="ZL_IDLIGNE" not-null="true" />
      <generator class="assigned" />
    </id>

<version column="ZL_VERSION" name="VERSION" type="Int32" access="property" unsaved-value="0" generated="never" />
    
     <many-to-one name="Piece" class="Piece" cascade="all">
        <column name="ZL_IDPIECE" not-null="true" />
     </many-to-one>

<property name="NATUREPIECEG" column="ZL_NATUREPIECEG" />
<property name="NUMERO" column="ZL_NUMERO" />
<property name="QTERESTEALIVRER" column="ZL_QTERESTEALIVRER" />
  </class>

</hibernate-mapping>


Here is what I try to do:

Code:
using (ISession session = m_SessionFactory.OpenSession())
{
                // Create a criteria object with the specified criteria
                ICriteria criteria = session.CreateCriteria(typeof(Piece));

               criteria.Add(Expression.Eq("IDPIECE", "anID"));
               criteria.Add(Expression.Gt("QTERESTEALIVRER", 0));
               
              // Get the matching objects
                IList<Piece> matchingObjects = criteria.List<Piece>();
}



But the following doesn't work

Code:
using (ISession session = m_SessionFactory.OpenSession())
{
                // Create a criteria object with the specified criteria
                ICriteria criteria = session.CreateCriteria(typeof(Piece));

               criteria.Add(Expression.Eq("IDPIECE", "anID"));
               criteria.CreateCriteria("Lignes").Add(Expression.Gt("QTERESTEALIVRER", 0));
               
              // Get the matching objects
                IList<Piece> matchingObjects = criteria.List<Piece>();
}



Thanks for your help in advance.

Thomas

Hibernate version: 2.0.50727

_________________
Thomas JASKULA - NODEVO
1, avenue du Général de Gaulle
60500 - Chantilly
+33 (0)3 44 26 36 72


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 10, 2008 5:16 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
I think you have to specifiy an alias for the sub criteria:

Code:
criteria.Add(Expression.Eq("IDPIECE", "anID")
      .CreateCriteria("Lignes", "l").Add(Expression.Gt("l.QTERESTEALIVRER", 0));

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 10, 2008 5:39 am 
Newbie

Joined: Fri Feb 22, 2008 5:39 am
Posts: 14
Thanks for your quick response.
I tired your code but the result is not what I expect.

for "anID" and QTERESTEALIVRER > 0 the result is :

Piece (anID)
- Ligne: first line
- Ligne: second line
Piece (anID)
- Ligne: first line
- Ligne: second line

instead of

Piece (anID)
- Ligne: first line
- Ligne: second line


I think that it returns as many "Piece" as many "Ligne" are in one "Piece".

Any ideas ?

Thanks in advance.

_________________
Thomas JASKULA - NODEVO
1, avenue du Général de Gaulle
60500 - Chantilly
+33 (0)3 44 26 36 72


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 10, 2008 6:10 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
This bahavior is true if you use join fetching. Couln't find that in your mapping, have you set it as default ? You can eliminate the duplicate references (it's the same object twice in the list not two different objects):

Code:
criteria.SetResultTransformer(CriteriaUtil.DistinctRootEntityResultTransformer);

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 10, 2008 8:33 am 
Newbie

Joined: Fri Feb 22, 2008 5:39 am
Posts: 14
Thanks wolli.

It works fine now :) What's the default behavior for joins ? Can I configure it in the mapping file ?

Another question not related to the problem. Sometimes I need to retrive only the root entity without child entities. By default if I retrive the root entity all child entities are retrieved too. Any ideas ?

Thanks in advance,

_________________
Thomas JASKULA - NODEVO
1, avenue du Général de Gaulle
60500 - Chantilly
+33 (0)3 44 26 36 72


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 10, 2008 8:44 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
You can configure it in the mapping, on the criteria or in hql. Have a look at

http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/performance.html#performance-fetching

mapping: <bag ... fetch="join" .../>

criteria: criteria.SetFetchmode(FetchMode.Join);

hql: from ... inner join fetch ...

configuration: <property name="use_outer_join">true</property>

There you'll also find more information about lazy loading, which would solve your second question.

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 11, 2008 4:23 am 
Newbie

Joined: Fri Feb 22, 2008 5:39 am
Posts: 14
Hello,

Thanks for your response.

I have noticed another problem. After I set up SetResultTransformer to DistinctRootEntity all works almost pretty good except that QTERESTEALIVRER > 0 is not beeing applied to the result. I get the lines with QTERESTEALIVRER = 0. Any ideas ?

Thanks in advance.

_________________
Thomas JASKULA - NODEVO
1, avenue du Général de Gaulle
60500 - Chantilly
+33 (0)3 44 26 36 72


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 11, 2008 10:41 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
That's the way it works. You get all parents, that match the criteria with all there childs. Have a look at the end of 12.4, there's a solution for it:

http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/querycriteria.html#querycriteria-associations

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 11, 2008 4:05 pm 
Newbie

Joined: Fri Feb 22, 2008 5:39 am
Posts: 14
I can't find out why when we create a subcriteria the filter doesnt work on childs ? QTERESTEALIVRER > 0 is a child filter. Tell me if i'm missing something but I don't really understand why to create a subcriteria if we can't apply any filtering.
I tried AliasToEntityMap for ResultTransformer but I get the following error "Unable to perform find".

Thanks in advance.

_________________
Thomas JASKULA - NODEVO
1, avenue du Général de Gaulle
60500 - Chantilly
+33 (0)3 44 26 36 72


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 15, 2008 4:38 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
The subcriteria is used to filter out parents which have no matching childs. But for all parents that are found, the complete entity is loaded, which means, all childs not only the matches.

That's the way it works. AliasToEnityMap should solve your problem, but I'm afraid I can't help you with this one, because I never used it before.

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 15, 2008 6:41 pm 
Newbie

Joined: Fri Feb 22, 2008 5:39 am
Posts: 14
Thanks for your help wolli. If anybody has an idea on how to achieve filtering on childs I'll be greatfull.

_________________
Thomas JASKULA - NODEVO
1, avenue du Général de Gaulle
60500 - Chantilly
+33 (0)3 44 26 36 72


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