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.  [ 2 posts ] 
Author Message
 Post subject: Question about criteria and composites.
PostPosted: Wed Jun 06, 2007 3:29 am 
Beginner
Beginner

Joined: Fri Jul 29, 2005 10:34 am
Posts: 25
Hibernate version: 1.2 GA

Mapping documents:
Code:
<composite-id unsaved-value ="any" >
      <key-many-to-one class ="Members" name="Members">
        <column name="`Member_id`" />
      </key-many-to-one>

      <key-many-to-one class ="Membership_Fees" name="Membership_Fees">
        <column name="`Member_id`" />
        <column name="`FeeDate`" />
      </key-many-to-one>

      <key-property name="PayDate" column="`PayDate`" type="System.DateTime" >
      </key-property>
    </composite-id>



The Code
Code:
  ICriteria _criteria = Session.CreateCriteria(typeof(MembersPaidFees),"MembersPaidFees");
 
  // Please notice that for "navigating" Members i don't need to create a nested criteria.
  _criteria.Add(new EqExpression("Members.Member_id" ,pMember_id));
 
  // If i apply the same pattern for the 2nd Key-Many-to-One
  _criteria.Add(new EqExpression("Membership_Fees.FeeDate" ,pFeeDate));
  _criteria.Add(new EqExpression("PayDate", pPayDate));
  _bo = (MembersPaidFees) _criteria.UniqueResult();
 



The Exception

base {NHibernate.QueryException: could not resolve property: Membership_Fees.FeeDate of: BOGlobalOptions_Test_BoLayer.MembersPaidFees
at NHibernate.Persister.Entity.AbstractPropertyMapping.ThrowPropertyException(String propertyName)
at NHibernate.Persister.Entity.AbstractPropertyMapping.ToColumns(String alias, String propertyName)
at NHibernate.Persister.Entity.AbstractEntityPersister.ToColumns(String alias, String propertyName)
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumns(String propertyName, ICriteria subcriteria)
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumnsUsingProjection(ICriteria subcriteria, String propertyName)
at NHibernate.Expression.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary enabledFilters)
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary enabledFilters)
at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, CriteriaImpl criteria, Type rootEntityName, IDictionary enabledFilters)
at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, Type rootEntityName, IDictionary enabledFilters)
at NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria, IList results)
at NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria)
at NHibernate.Impl.CriteriaImpl.List()
at NHibernate.Impl.CriteriaImpl.UniqueResult()} NHibernate.HibernateException {NHibernate.QueryException}

The workaround
_criteria.CreateCriteria("Membership_Fees").Add(new EqExpression("FeeDate", pFeeDate));

What i don't understand is why a nested criteria is needed for "Membership_Fees" and
it's not needed for "Members".

At one moment i thought it could be the fact of multiple columns but it's not that since
i have the same issue in:

Code:
  <composite-id unsaved-value ="any" >
      <key-many-to-one class ="Books" name="Books"  >
        <column name="`ISBNNumber`" />
      </key-many-to-one>
      <key-many-to-one class ="Members" name="Members"  >
        <column name="`Member_id`" />
      </key-many-to-one>
    </composite-id>


Conclusion : it looks like only the 1st key-many-to-one is processed and the rest ignored.

Note: I would like to help in the NHibernate source if somebody gives any hint.

Can someone confirm if this is a bug / and if i should post it to JIRA?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 15, 2007 4:53 am 
Beginner
Beginner

Joined: Sat Sep 17, 2005 6:50 am
Posts: 23
I have met the same problem with this limitation. Seems like <key-many-to-one> definitiona automatically uses outer-join="true" (and there is no way to override this). That's why it is not possible to define such property reference as "entity.key.property", as "key.property" cannot be defined while building the query.

So, the only way is to use the subquery, which can be created using the DetachedCriteria. In your case (Java code):

Code:
final DetachedCriteria innerCriteria = DetachedCriteria.forClass(Membership_Fees.class).setProjection(Property.forName("id"));

innerCriteria.add(Restrictions.eq("Member_id", some_id));
innerCriteria.add(Restrictions.eq("FeeDate", some_date));

criteria.add(Property.forName("Membership_Fees").in(innerCriteria));

However, it is not evident, what is the key for your Membership_Fees component. It seems to be composite, then we need Hibernate support for correct "exist" subquery for keys:

Code:
criteria.add(Subqueries.exists(innerCriteria));

which should generate:

Code:
select ... from Membership where exist
(select Member_id, FeeDate from Membership_Fees _this where Membership.Member_id = _this.Member_id and Membership.FeeDate = _this.FeeDate)


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