I am using nHibernate to try and log a user in using a named query but their password is hashed and so stored as a binary field in the MS SQL DB. However I can't get the login code to work. It throws an error:
using (var session = sessionFactory.OpenSession())
{
user = (CreamUser)session.GetNamedQuery("loginuser")
.SetString("UserName", userName)
.SetBinary("Password", hashedPassword).UniqueResult();
}
<sql-query name="loginuser">
<query-param name="UserName" type="string" />
<query-param name="Password" type="binary" />
<return alias="User" class="components.User"/>
<![CDATA[
SELECT * FROM users
WHERE username=:UserName AND
password=:Password
]]>
</sql-query>
I have tried everything I can think of but can't get this to work.
Ok so I worked it out. I turns out it was to do with the fact the the query I was executing was missing some fields that matched with the type (user) that I was returning.
this was the error in case anyone else comes across this issue:
could not execute query\r\n[ SELECT * FROM users \n WHERE username=#p0 AND \n
password=#p1 ]\r\n Name:UserName - Value:admin Name:Password - Value:System.Byte[]\r\n[SQL:
SELECT * FROM users \n WHERE username=#p0 AND \n password=#p1]
thanks for making me look deeper ExpectoPatronum
How can I specify the length of string input parameters of a stored procedure in Nhibernate mapping files.
this is my mapping contents
<sql-query name="Sp_News" resultset-ref="NewsPackResultSet" cacheable="false">
<query-param name="SearchString" type="System.String" />
<query-param name="StartDate" type="System.DateTime" />
exec dbo.Sp_News:SearchString,:StartDate
</sql-query>
When the length of SearchString parameter is more than 4000 characters, the Nhibernate Truncates that parameter values. How can i solve this limitation?
any help would be appreciated.
Found this question and also found the answer:
IQuery query = session.GetNamedQuery("Sp_News");
query.SetParameter("SearchString", longString, NHibernateUtil.StringClob);
NHibernateUtil.StringClob is the key :-)
I have an object model where a Calendar object has an IDictionary<MembershipUser, Perms> called UserPermissions, where MembershipUser is an object, and Perms is a simple enumeration. This is in the mapping file for Calendar as
<map name="UserPermissions" table="CalendarUserPermissions" lazy="true" cascade="all">
<key column="CalendarID"/>
<index-many-to-many class="MembershipUser" column="UserGUID" />
<element column="Permissions" type="CalendarPermission" not-null="true" />
</map>
Now I want to execute a query to find all calendars for which a given user has some permission defined. The permission is irrelevant; I just want a list of the calendars where a given user is present as a key in the UserPermissions dictionary. I have the username property, not a MembershipUser object. How do I build that using QBC (or HQL)? Here's what I've tried:
ISession session = SessionManager.CurrentSession;
ICriteria calCrit = session.CreateCriteria<Calendar>();
ICriteria userCrit = calCrit.CreateCriteria("UserPermissions.indices");
userCrit.Add(Expression.Eq("Username", username));
return calCrit.List<Calendar>();
This constructed invalid SQL -- the WHERE clause contained WHERE membership1_.Username = #p0 as expected, but the FROM clause didn't include the MemberhipUsers table.
Also, I really had to struggle to learn about the .indices notation. I found it by digging through the NHibernate source code, and saw that there's also .elements and some other dotted notations. Where's a reference to the allowed syntax of an association path? I feel like what's above is very close, and just missing something simple.
Just trying to do this myself and it looks like this can be done with HQL but not the Criteria API.
https://nhibernate.jira.com/browse/NH-1795
To do it in HQL:
http://ayende.com/Blog/archive/2009/06/03/nhibernate-mapping-ndash-ltmapgt.aspx
Specifically look for Ayende's comment:
It is something like:
select 1 from Profile p join p.Entries e
where index(e) = 'HasCats' and e = 'true'
i have an sql query that has one unnamed column as a list of strings.
my hbm is declared as follows:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Services.Data" namespace="Services.Data" >
<sql-query name="GetDiagramSubscriptions">
exec Diagram_Subscriptions:contactId
</sql-query>
</hibernate-mapping>
my repository method:
IQuery query = Session.GetNamedQuery("GetDiagramSubscriptions")
.SetInt32("contactId", contactId)
.SetResultTransformer(Transformers.AliasToBean<string>());
return query.List<string>();
this doesn't work because type string doesn't have a setter.
i don't want to declare a mapping class just for this one column. is there a way to transform this to a Tuple or something?
just remove this call .SetResultTransformer(Transformers.AliasToBean<string>()) and the List<string>() will do what you expect.
I need help with NHibernate. I'm using 2.1, but have tried this on 3 as well, with same results. Any help most appreciated!
When doing an ICriteria query using NHibernate, it executes both the query, and then for each result in the query, it executes another query to select an associated object, which is already returned in the initial resultset as I am using eager loading. This is of course resulting is dismal performance. Using the mapping file below, the query Nhibernate generates is exactly as expected below :
exec sp_executesql N'SELECT top 20 this_.ContactCode as ContactC1_48_1_, this_.IsActive as IsActive48_1_, contact2_.ContactCode as ContactC1_47_0_, contact2_.ContactFullName as ContactF2_47_0_ FROM Clients this_ left outer join Contacts contact2_ on this_.ContactCode=contact2_.ContactCode WHERE this_.ContactCode like #p0 and this_.IsActive = #p1 ORDER BY this_.ContactCode asc',N'#p0 nvarchar(7),#p1 bit',#p0=N'DAL001%',#p1=1
This query returns a single record, however is followed immediately with the following query, which is retrieving the details for the related contact object, which is already returned in full in the initial query, and of course, when returning many records, N addition queries are executed. This is completely unexpected!
exec sp_executesql N'SELECT contact0_.ContactCode as ContactC1_47_0_, contact0_.ContactFullName as ContactF2_47_0_ FROM Contacts contact0_ WHERE contact0_.ContactCode=#p0',N'#p0 nvarchar(6)',#p0=N'DAL001'
Lazy loading is switched off. The ICriteria code is as follows :
ICriteria clientsFromContactCodeQuery = session.CreateCriteria<Client>()
.Add(Restrictions.Like("ContactCode", id + "%"))
.Add(Restrictions.Eq("IsActive", true))
.AddOrder(Order.Asc("ContactCode"))
.SetMaxResults(maxResultCount);
var clientsFromContactCodeList = clientsFromContactCodeQuery.List();
I have a simple nhibernate mapping file :
<class name="Contact" table="Contacts" lazy="false">
<id name="ContactCode">
<generator class="assigned" />
</id>
<property name="ContactFullName" />
</class>
<class name="Client" table="Clients" lazy="false">
<id name="ContactCode">
<generator class="assigned" />
</id>
<property name="IsActive" />
<one-to-one
name="Contact"
class="Contact"
lazy="false"
fetch="join"
/>
</class>
Turn on lazy loading and then use HQL queries to prefetch required children.
from Client c
left join fetch c.Contact
where
c.ContactCode like :id
and
c.IsActive eq true
I don't know the order by syntax off the top of my head and the HQL may need to be tweaked a bit, but that's the core of the solution.
Try setting your max_fetch_depth property to 2 or 3 if you have not. Not sure if this works with one-to-one relationships though.
<property name="max_fetch_depth">3</property>
Most bizarrely, after trying various changes to the query, from hql to icriteria formats, nothing worked. However, I noticed some data where the N+1 queries were not being generated. It turns out the primary keys in the contacts and clients table has SPACES at the end, which when removed, fixed the problem!
Very strange, but thanks for the help.