NHibernate HQL logic problem

走远了吗. 提交于 2020-01-01 16:33:11

问题


I'm trying to write an NHibernate HQL query that makes use of parenthesis in the where clause. However, the HQL parser seems to be ignoring my parenthesis, thus changing the meaning of my statement. Can anyone shed any light on the matter?

The following HQL query:

from WebUser u left join fetch u.WebUserProfile left join fetch 
u.CommunicationPreferences where (u.CommunicationPreferences.Email = 0 and
u.SyncDate is not null) or u.DateDeleted is not null

translates to:

from   WebUser webuser0_
left outer join WebUserProfile webuserpro1_
on webuser0_.UserId = webuserpro1_.WebUserId
left outer join WebUserCommunicationPreferences communicat2_
on webuser0_.UserId = communicat2_.UserId
where  communicat2_.Email = 0
and (webuser0_.SyncDate is not null)
or webuser0_.DateDeleted is not null

Thanks

Jon


回答1:


I know this is a late answer but I had to add my two cents.

In SQL the and operator takes precendence over the or operator. So

(u.CommunicationPreferences.Email = 0 and u.SyncDate is not null) or u.DateDeleted is not null

is the same as

communicat2_.Email = 0 and (webuser0_.SyncDate is not null) or webuser0_.DateDeleted is not null




回答2:


The left join that you specify in the from clause, must be respected in all criterias in the where clause. You must take care of the special null case in all parts of the query, this is the way SQL (and HQL) works.

Reference : http://en.wikipedia.org/wiki/Null_(SQL)

when you write u.CommunicationPreferences.Email = 0, the CommunicationPreferences must be not null, or the database row will not be selected.

I suggest trying the following (adapt it to your own case) :

from WebUser u 
  left join fetch u.WebUserProfile w
  left join fetch u.CommunicationPreferences c
where ( (c.Email = 0 or c is null) 
         and u.SyncDate is not null) 
or u.DateDeleted is not null

Extract from the HQL Best-practices on our projects :

  • give aliases to all tables reached
  • for each nullable alias (w and c in this case), any constraint (c.Email = 0) must be or-ed with the null case (or c is null)

Added: To explain more :

The second LEFT join means that you want to select a WebUser even if there is no CommunicationPreferences that match. This is incompatible with a selection like u.CommunicationPreferences.Email, that excludes any match if u.CommunicationPreferences is null (read well, I don't refer to the Email column).

Such an incompatibility may cause strange translations, where you don't understand why the SQL was created that way ... Fix the HQL and try again :-) The parenthesis may become correct.



来源:https://stackoverflow.com/questions/1287300/nhibernate-hql-logic-problem

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!