How to use bitwise operators in HQL? - nhibernate

In HQL, how can I use bitwise operators? I want the resulting SQL query to look something like
SELECT RoleId, RoleName, RolePerms WHERE (RolePerms & #Parameter) = #Parameter
However, writing this HQL
select from Role where (RolePerms & :param) = :param
gives me this error: NHibernate.Hql.Ast.ANTLR.QuerySyntaxException: Exception of type 'Antlr.Runtime.NoViableAltException' was thrown.

I found a solution to this. Writing the HQL this way works:
select r from Role r where (r.Permissions & :param) > 0

From section 13.8 of the NHibernate documentation, HQL does not support these bitwise operators. You'd have to revert to native SQL (see section 15).

According to the NHibernate Jira it looks like this should be working as of 2.1.0Beta2, https://nhibernate.jira.com/browse/NH-1192.

Related

Convert mysql query to HQL

select distinct gv.geoname,gv.GeoHierLevelCode,
SUBSTRING_INDEX(SUBSTRING_INDEX(gd.geohierpath,'/',4),'/',-1)
from HavellsUserSalesForceMapping hs,geohiervalue gv,geohierpathdetails gd
where hs.userCode = '00000001'
and hs.cmpCode = gv.cmpCode
and gv.geoCode IN (hs.geoCode)
and gd.geohierpath LIKE CONCAT('%/',gv.geoCode,'/%') ;
SUBSTRING_INDEX is getting issue for me.Tell me the actual way to convert to hql
Use #Formula annotation and define a dummy field for your expression. Then the field could be used in HQL query.

Expressing IN sql statement in Linq with computed string in where clause

I'm trying to build a linq query for the following sql query :
SELECT *
FROM [QryFiles2]
WHERE (left(Demande,6) IN (select NoBVR from tblRequest))
Knowing that QryFiles2 is an entity and tblRequest too I've come to something like that :
from f in db.QryFiles2
where f.Demande.Substring(0,6) /* in (select NoBVR from tblRequest) */
select f
The thing is I don't know how I could express the in sql statement using linq. Do you know how I could do that without using raw sql queries ?
Nb : I've tried to use the .contains method but I couldn't work it out with the computed substring.
Finally I've done this using a join statement like that :
from f in db.QryFiles2
join r in db.tblRequest on f.Demande.Substring(0,6) equals r.NoBVR
Super clean super fast no need for subqueries should have thought about that before :-)

LINQ To NHibernate ignores the 'Group by' clause

I use NHibernate 3.2.0 and I cannot make the LINQ provider generate a proper SQL query for this statement:
var result = (from translation in session.Query<TmTranslation>()
where translation.Id > 0
group translation by translation.Language into grp
select new { Lang = grp.Key.Code }).ToList();
The generated SQL is
select tmtranslat0_.id as id32_,
tmtranslat0_.status as status32_,
tmtranslat0_.text as text32_,
tmtranslat0_.last_revision as last4_32_,
tmtranslat0_.fk_id_translation_unit as fk5_32_,
tmtranslat0_.fk_id_translator as fk6_32_,
tmtranslat0_.fk_id_last_modifier as fk7_32_,
tmtranslat0_.fk_id_last_match_category as fk8_32_,
tmtranslat0_.fk_id_language as fk9_32_
from "TRANSLATION" tmtranslat0_
where tmtranslat0_.id > 0
which, of course leads to loading all the entities from the database and grouping the result set in memory (the result itself is correct).
I would like something like this
select tmtranslat0_.fk_id_language
from "TRANSLATION" tmtranslat0_
where tmtranslat0_.id > 0
group by tmtranslat0_.fk_id_language
to be generated instead.
Am I missing something?
Thank you very much.
The only thing I can suggest, is to use QueryOver API.

How to select if a row exists in HQL

EDIT: Specifically talking about querying against no table. Yes I can use exists, but I'd have to do
select case when exists (blah) then 1 else 0 end as conditionTrue
from ARealTableReturningMultipleRows
In T-SQL I can do:
select case when exists(blah) then 1 else 0 end as conditionTrue
In Oracle I can do:
select case when exists(blah) then 1 else 0 end as conditionTrue from DUAL
How can I achieve the same thing in HQL?
select count() seems like the second-best alternative, but I don't want to have to process every row in the table if I don't need to.
Short answer: I believe it's NOT possible.
My reasoning:
According to Where can I find a list of all HQL keywords? Hibernate project doesn't publish HQL grammar on their website, it's available in the Hibernate full distribution as a .g ANTLR file though.
I don't have much experience with .g files from ANTLR, but you can find this in the file (hibernate-distribution-3.6.1.Final/project/core/src/main/antlr/hql.g):
selectFrom!
: (s:selectClause)? (f:fromClause)? {
// If there was no FROM clause and this is a filter query, create a from clause. Otherwise, throw
// an exception because non-filter queries must have a FROM clause.
if (#f == null) {
if (filter) {
#f = #([FROM,"{filter-implied FROM}"]);
}
else
throw new SemanticException("FROM expected (non-filter queries must contain a FROM clause)");
}
which clearly states there are some HQL queries having no FROM clause, but that's acceptable if that's a filter query. Now again, I am not an expert in HQL/Hibernate, but I believe a filter query is not a full query but something you define using session.createFilter (see How do I turn item ordering HQL into a filter query?), so that makes me think there's no way to omit the FROM clause.
I'm use fake table with one row for example MyDual.
select case when exists(blah) then 1 else 0 end as conditionTrue from MyDual
According to http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html#queryhql-expressions it looks like they support both case and exists statements.

Nhibernate upgraded getting 'Antlr.Runtime.NoViableAltException' on outer join using *=

so we upgraded to newer Nhibernate and Fluent Nhibernate.
now I' getting this exception:
FailedNHibernate.Hql.Ast.ANTLR.QuerySyntaxException: Exception of type 'Antlr.Runtime.NoViableAltException' was thrown. near line 1, column 459
On this hql, which worked fine before the upgrade.
SELECT s.StudId, s.StudLname, s.StudFname, s.StudMi, s.Ssn, s.Sex, s.Dob, et.EnrtypeId, et.Active, et.EnrId, sss.StaffLname, sss.StaffFname, sss.StaffMi,vas.CurrentAge FROM CIS3G.Jcdc.EO.StudentEO s , CIS3G.Jcdc.EO.EnrollmentEO e , CIS3G.Jcdc.EO.EnrollmentTypeEO et , CIS3G.Jcdc.EO.VwStaffStudentStaffEO sss, CIS3G.Jcdc.EO.VwAgeStudentEO vas WHERE ( e.EnrId = et.EnrId ) AND ( s.StudId = vas.StudId ) AND ( s.StudId = e.StudId ) AND ( et.EnrtypeId *= sss.EnrtypeId ) AND ( Isnull ( sss.StudStaffRoleCd , 1044 ) = 1044 ) AND ( s.StudId = 4000 )
Clearly it does nto like the *= syntax, I tried rewritign is as ansi sql outer join and no joy.
Can anyone tell me what ineed to change the sql to so I can get the outer join to work correctly?
Thanks,
Eric-
We got it working with the ansi sql and calling nhibernate slightly differently.
Is there any way to force antlr to allow t-sql, or to stop antlr parsing all together?
All this sql worked fine before we got the version that added antlr parsing.
In MANY places we are passing T-Sql to NHibernate, becasue we're porting from another app with all the complex SQl already written, and We'd like to avoid having to rewrite & retest all the sql as ansi standard.
Shouldn't the antrl parsing only be applied to HQL only not direct SQL anyway? You reduce the
native compatibility for other DBs, like ours.
Thanks,
Eric=
You don't need to do explicit joins with NHibernate in order to get the related entities. Instead, map those relations as many-to-one.
For example, your Student class could have a References(x => x.EnrollmentType). With that, you'd only need to select the student (you don't even need HQL if you know the Id; you can use session.Get) and you could just navigate to the other properties.
I recommend you read the NHibernate documentation