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: problems w/ IQuery.SetProperties (interfaces + collections)
PostPosted: Tue Jun 19, 2007 11:40 am 
Beginner
Beginner

Joined: Tue Jul 19, 2005 11:21 am
Posts: 23
Location: erie, pa
I'm trying to execute a query by settings its parameters via the SetProperties() method on IQuery. I am having 2 separate but related issues. But first, my code...

The HQL:

FROM CarrierService cs
WHERE cs.Carrier = :Carrier
AND cs.Service in (:Services)

Notice the first parameter is a mapped entity object and the second parameter is a collection of mapped entities. This query works fine when using query.SetParameter and query.SetParameterList. The issue arises when trying to introduce a criteria object...

public class CarrierServiceQueryCriteria : QueryCriteria<ICarrierService>
{
private ICarrier carrier;
private IShippingService[] services;

public ICarrier Carrier
{
get { return carrier; }
set { carrier = value; }
}

public IShippingService[] Services
{
get { return services; }
set { services = value; }
}
}

When I try to run the query by setting the parameters via the SetProperties method (and passing in a properly constructed instance) I get the error:

NHibernate.QueryException: Not all named parameters have been set: [Carrier] [
FROM CarrierService cs
WHERE cs.Carrier = :Carrier
AND cs.Service in (:Services)
]


Apparent problem: It appears the logic behind SetProperties() doesn't handle the domain objects' interfaces. Using the class is not an option since we are using interfaces for lazy loading and such.

So then I tried changing my query/object to just pass the integer key values...

The new HQL:
FROM CarrierService cs
WHERE cs.Carrier.Id = :CarrierId
AND cs.Service.Id in (:ServiceIds)


The new class:

public class CarrierServiceQueryCriteria : QueryCriteria<ICarrierService>
{
private int carrierId;
private int[] serviceIds;

public int CarrierId
{
get { return carrierId; }
set { carrierId = value; }
}

public int[] ServiceIds
{
get { return serviceIds; }
set { serviceIds = value; }
}
}

The query no longer throws an exception but does not return results. Turning on show_sql reveals the problem:

NHibernate: select ... from CarrierService carrierser0_ where (carrierser0_.Carrier=@p0 )AND(carrierser0_.Service in(@p1)); @p0 = '149', @p1 = 'System.Byte[]'

Notice how @p1 is being set to the type name. Apparent problem: The query logic didn't pick up on the fact that I wanted a parameter list.


For comparison, here is the SQL generated when I run the same HQL by setting parameters via SetParameter and SetParameterList:

NHibernate: select ... from CarrierService carrierser0_ where (carrierser0_.Carrier=@p0 )AND(carrierser0_.Service in(@p1 , @p2 , @p3 , @p4 , @p5 , @p6 , @p7 , @p8 , @p9 , @p10 , @p11 , @p12 , @p13 , @p14 , @p15)); @p0 = '149', @p1 = '1', @p2 = '8', @p3 = '17', @p4 = '12', @p5 = '3', @p6 = '15', @p7 = '18', @p8 = '4', @p9 = '10', @p10 = '5', @p11 = '16', @p12 = '11', @p13 = '19', @p14 = '20', @p15 = '7'


Am I doing something wrong or are these 2 things limitations of the SetProperties method logic?

I checked over the documentation and searched the net and these forums and could not find any relevant discussion. I tried looking at the NH source code but could not make sense of what I was looking at.

Is this something planned to be added to the code base? Does it need a volunteer? Can someone point me to the right place(s) where this would need to get implemented? I need this functionality and am willing to implement it with some assistance and knowing that it would eventually get integrated into the official code base. Please advise.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 19, 2007 1:04 pm 
Beginner
Beginner

Joined: Tue Jul 19, 2005 11:21 am
Posts: 23
Location: erie, pa
Looking at the implementation of AbstractQueryImpl.SetProperies:

Code:
      public IQuery SetProperties(object bean)
      {
         System.Type clazz = bean.GetType();
         foreach (string namedParam in actualNamedParameters)
         {
            try
            {
               IGetter getter = ReflectHelper.GetGetter(clazz, namedParam, "property");
               SetParameter(namedParam, getter.Get(bean), GuessType(getter.ReturnType));
            }
            catch (Exception)
            {
            }
         }
         return this;
      }


I noticed there is an empty catch block. It seems to me like it should just let the exception happen if the containing code fails. Or catch and throw a more informative exception.


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.