Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

This problem arises because NHibernate tries to access the column without the type length. Hence in the HBM.xml its very important to mention length for Legacy databases otherwise it will fail for UNIcode related stuff.

Thanks, Thani

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top