views:

984

answers:

3

In SQL one can write a query that searches for a name of a person like this:

SELECT * FROM Person P WHERE P.Name LIKE N'%ike%'

This query would run with unicode characters (assuming that the Name column and database were setup to handle unicode support).

I have a similar query in HQL that is run by Hibernate (NHibernate). The generated query looks like:

SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%カタカ%'  )

Unfortunately, placing a 'N' in front of the literal in the HQL results in an error. I've tried escaping the unicode characters in the string and still no success.

The database is accepting and saving unicode characters from Hibernate. I've been able to successfully populate an object with a unicode string, save it with Hibernate, and verify it in the database. It would seem to me as a little odd that I cannot use unicode strings in custom queries (or I'm also assuming named queries).

Is this a known issue or limitation of Hibernate (Nhibernate)? How do you use unicode in HQL?

Several sites suggest using the Criteria queries. Due to constraints in the framework that I'm working in, this is not possible.

+1  A: 

Have you tried with parameters:

IList<Person> people = session
    .CreateQuery("from Person p where p.Name like :name")
    .SetParameter("name", "%カタカ%")
    .List<Person>();

They also have the advantage to protect your query against SQL injection.

Darin Dimitrov
I'm recursively building a complex query string with different criteria and operations. I have a provider that I pass an operation and term into to get the 'Like' portion back. This would work if I were not doing that! I was hoping there was some magic escape character.
Mike G
A: 

I found a solution that works. I highly doubt it is the best solution. It is however the solution that I'm going to implement until I can authorize a rewrite of the entire query building section of the software that I'm working on.

In the instance:

SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%カタカ%')

The where clause contains this literal:

'%カタカ%'

This literal can be broken up into nchars which Hibernate (Nhibernate) will unknowingly pass through to the SQL it generates. Odd, but it works. Thus the previous query could be written as:

SELECT P FROM SumTotal.TP.Models.Party.Person P join P.Demographics PD WHERE (PD.LastName LIKE '%' + nchar(0x30AB) + nchar(0x30BF) + nchar(0x30AB)+ '%')

This solution is far from optimal because it would require going through each character and determining if it was a multibyte character. However, in the case of where this code lives in its app it is used in a dynamic query generator that processes multiple different criteria under different operations. In the example I give it is looking for unicode anywhere in the string. It is possible that this function may be returning the where clause portion for a column equaling a specific numeric value or it could be looking for the starting characters of a string. The method that builds the operator uses a operator type and the term to hand back a string. I could rewrite that but it would be a large task. The above fix will allow me to process a string passed into this method. I offer this solution because it does work, but darin's answer is probably the best way I could find.

Mike G
A: 

Well , i tried the parameter way and yeah its working. So who want to use NHibernate with nvarchar comparison use Paramteres

Moutasem al-awa