Using an INNER JOIN to join two tables in HQL - sql

I have an SQL query that I need to convert to an HQL query.
I have a class Item that contains a set of Components. The SQL table for Item is DBO.W_ITEM and the table for Component is DBO.W_COMPONENT.
In SQL, I've had no trouble doing this like so...
SELECT
item.noun,
comp.type
FROM
DBO.W_ITEM item
INNER JOIN DBO.W_COMPONENT comp ON item.id = comp.id
However, I can't get this to work in HQL.
I've tried it like this...
SELECT
item.noun,
comp.type
FROM
InventoryItemInv item
INNER JOIN item.components comp ON item.id = comp.id
but the HQL doesn't seem to know what to do with the ON - and says it's an unexpected token. According to all the literature, HQL supports the ON keyword.
Any suggestions?
Thanks in advance!

You don't need to use the ON clause to define the binding column, Hibernate will infer it from the relationship defined in the model, following HQL query should work for you
SELECT item.noun, comp.type
FROM InventoryItemInv item
INNER JOIN item.components comp

Related

Hibernate criteria query for join with condition

I have the following SQL query:
SELECT
tos.ID
FROM
TESTCYCLE_OPCO_SETTING tos
JOIN OPCO o
ON o.ID = tos.OPCO_ID
JOIN TESTCYCLE tc
ON tc.ID = tos.TESTCYCLE_ID
LEFT OUTER JOIN BUILD b
ON b.ID = tc.BUILD_ID
LEFT OUTER JOIN BUILD_OPCO_SETTING bos
ON bos.BUILD_ID = b.ID
AND bos.OPCO_ID = o.ID
What is needed is that the OPCO_ID form the TESTCYCLE_OPCO_SETTING is used to fetch the corresponding BUILD_OPCO_SETTING. I have done this with the "AND" condition in the last JOIN.
I now want to create a Hibernate Critera query out of this and created the following aliases for the joins:
criteria.createAlias("opco", "opco");
criteria.createAlias("testcycle", "testcycle");
criteria.createAlias("testcycle.build", "build", CriteriaSpecification.LEFT_JOIN);
criteria.createAlias("build.buildOpcoSettings", "buildOpcoSetting", CriteriaSpecification.LEFT_JOIN, Restrictions.eqProperty("buildOpcoSetting.opco.id", "opco.id"));
However the 4th alias throws an SQL error and I think I'm using this incorrectly for what I want to achieve. If I replace the property "opco.id" with a specific numeric value it works but this doesn't help me of course.
Any ideas?
Found the solution myself. Using the "opco" alias within the "buildOpcoSetting" alias lead to a wrong order of joins in the resulting SQL and an extra "opco" join. Replaced it with the opco reference from the "testcycleOpcoSetting" which works fine.
criteria.createAlias("build.buildOpcoSettings", "buildOpcoSetting", CriteriaSpecification.LEFT_JOIN,Restrictions.eqProperty("buildOpcoSetting.opco.id", "testcycleOpcoSetting.opco.id"));

NHibernate query fails with "the multi-part identifier could not be bound" on an aggregate query

I'm trying to understand why this simple query is generating the wrong SQL on NHibernate 3.3:
var query = session.CreateQuery(#"select count(*) as C
from Parent p
inner join fetch p.Child c
where c.Field = 'someValue'");
When I execute this query the generated SQL does NOT include a reference to the Child table, which causes the dreaded "the multi-part identifier _child.FIELD could not be bound" exception.
Anyone has an idea on why this problem and how to solve it?
Thanks!
Assign a different alias to count(*), probably nhibernate is getting confused since you're using c and C as aliases.
For instance, you could set your query like this
var query = session.CreateQuery(#"select count(*) as co
from Parent p
inner join fetch p.Child c
where c.Field = 'someValue'");
Just for reference, if someone else gets burned by this.
It seems the internals of NHibernate are filtering out join when generating the query.
So, the only solution we found was to rephrase the query this way:
select count(*) as C
from Parent p
where p.Child.Field = 'someValue'
This way, NHibernate is going to generate the join syntax (using cross join operators and where clauses).

HQL: Is it possible to perform an INNER JOIN on a subquery?

The diagram above is a simplified version of the database structure that I use to log item locations through time. I wrote the following SQL query which returns the current item inventory of each location:
select *
from ItemLocationLog l
inner join
(select g.idItemLocationLog, max(g.dateTime) as latest
from ItemLocationLog g
group by g.idItem)
as i
on l.idItem = i.idItem and l.dateTime = i.latest
The problem I'm having is that I want to convert that to HQL, but I haven't found the syntax to perform an INNER JOIN on a subquery, and it seems like this is not supported. Is there a way to convert the above to HQL (or a Criteria) or will I have to use a standard SQL query in this case? Thanks.
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-subqueries
Note that HQL subqueries can occur only in the select or where clauses.
You can rewrite the query so that the subquery is part of the where clause instead. Referencing the l.idItem in the subquery

How can I convert this code from SQL to Linq

How can I convert this below code from SQL to Linq
SELECT CF.CustomerProfileId,CF.Salutation,CF.Gender,CF.LastName,
CF.DateOfBirth,AD.Line1,AD.Line2,AD.Line3,AD.Line4,AD.Line5,
AD.Country,AD.ElectronicAddressDesc,NCIType.NationalCustomerIdentifierTypeDesc,
NCI.NationalCustomerIdentifier from CustomerProfile CF
left join Address AD on CF.CustomerProfileId = CF.CustomerProfileId
left join NationalCustomerIdentifiers NCI on CF.CustomerProfileId = NCI.CustomerProfileId
left join NationalCustomerIdentifierType NCIType on NCI.NationalCustomerIdentifierTypeId = NCIType.NationalCustomerIdentifierTypeId
where CF.CustomerProfileId = #CustomerProfileid and CF.Version = #Version
You need to make several left joins in LINQ. This is possible though will look not very good (linq is not very comfortable when dealing with joins other than inner).
Here is a microsoft example of left join in linq It only joins two tables but you can extend it. And if you don't like how the result looks - than make a view or an sproc.

NHibernate HQL subselect left join?

I have the following issue and I would really appreciate your help:
I have all my filtering done through the HQL and one of the filters is a left outer join which must be a sub-select. So my thinking here is that I can create a dummy business object which I would like to populate (with an SP if possible) with data and use it in my left join.
Now how can I do that and still have all of the logic in 1 HQL query?
I guess the biggest issue for me is understanding how can I have this BO (not actually mapped to a table etc.) be used in a query where all the other BOs are mapped to tables etc.
I am trying to avoid doing any filtering in the actual C# code.
Thanks!
Example:
Entity A - mapped to table A
Entity B - mapped to table B
Entity C - mapped to table C
Entity D - not mapped to table - coming from SQL query or SP
HQL:
from A pbo
inner join B.EntityType etype
inner join C.EntityAddressList eadr
left join D.Level lvl
You cannot join to arbitrary SQL in HQL. So I don't think what you're trying to do is possible. You'll likely either have to map whatever D is, or write your query in SQL using Session.CreateSQLQuery(). You can still specify any entities that come back. See this article for reference. http://www.nhforge.org/doc/nh/en/index.html#d0e10274