Using Left Joins in HQL on 3 Tables - hql

I have three tables A B and C. Now i want to execute this sql query in HQL:
select * from A as a
left join
B as b
on
a.id = b.id
left join
C as c
on
b.type=c.type;
Need help in writing equivalent HQL. I tried with this HQL...
Query q = session.createQuery(
"FROM A as a
LEFT JOIN
B as b
on
a.id=b.id
LEFT JOIN
C as c
on
b.type=c.type");
This query is throwing exception .....
org.hibernate.hql.ast.QuerySyntaxError: unexpected token: LEFT near
line 1, column 23 [FROM com.admin.A as a LEFT JOIN B as b where
a.Id=b.Id LEFT JOIN C as c where b.type=c.type] at
org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:74)
at
org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:214)
at
org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:127)
at
org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:83)
at
org.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:414)
I also tried with "with" and "on" clauses instead of where...I get the same unexpected token on "on" or "with"
exception qith ON .....
org.hibernate.hql.ast.QuerySyntaxError: unexpected token: ON near line
1, column 41 [FROM com.admin.A as a LEFT JOIN B as b on a.Id=b.Id LEFT
JOIN C as c onb.type=c.type] at
org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:74)
at
org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:214)
at
org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:127)
at
org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:83)
at
org.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:414)
I also tried with "with" clauses instead of where...I get the same unexpected token on or "with"
exception qith WITH .....
org.hibernate.hql.ast.QuerySyntaxError: unexpected token: ON near line
1, column 41 [FROM com.admin.A as a LEFT JOIN B as b on a.Id=b.Id LEFT
JOIN C as c onb.type=c.type] at
org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:74)
at
org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:214)
at
org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:127)
at
org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:83)
at
org.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:414)
Please help.

I suppose you've already defined all the needed associations in your configuration. If so, in HQL it would look like this:
from A as a left join a.B as b left join b.C as c
There is no "ON" statement in HQL, hibernate does automatically based on your mappings and defined Associations.
Pay attention to a.B and b.C.
You refer to B and C based on already defined aliases a & c.

Use this query
from A as a
left join fetch a.B as b
left join fetch b.C as c

Related

How to associate three tables?

I have three tables ABC. I hope to display all records of A while linking BC. Field a1 of A is associated with field b1 of B. a1 may be empty, so I wrote
A.a1=B.b1(+)
The two fields c and d of table C are associated with A.a2 and B.b2 respectively
so i wrote
A.a2 = C.c(+) and B.b2 = C.d(+)
The total sql is as follows
select A.a1, A.a2, B.e,C.f,
from A, B, C
where A.a1=B.b1(+)
and A.a2 = C.c(+)
and B.b2 = C.d(+)
But the prompt says that a table can only have one external link at most.
I tried to use case when to display the information of B and C,
select A.a1, A.a2,
case when a1 is null then null
else (selece B.e from B
where B.b1=A.a1) end,
case when a1 is null then null
when (selece B.e from B
where B.b1=A.a1) is null then null
else (selece C.f from C
where C.c=A.a2 and C.d=B.b2) end
from A
but is there any other better association method?
"Older" (I believe lower than 21c) Oracle database versions won't let you outer join one table to two or more other tables using the "old" Oracle's (+) outer join operator.
But, if you switch to JOINs, then you won't have that problem. Something like this:
select *
from b left join a on a.a1 = b.b1
left join c on c.d = b.b2 and c.c = a.a2
(Fetch columns you want, include conditions you need, but - that's the general idea.)

Left outer join is null- additional conditions

I'm trying to find all entries in table a, where there is no matching entry in table b for one specific column (order). I'm using the following:
SELECT *
FROM a
LEFT OUTER JOIN b
ON a.id = b.id
WHERE b.order IS NULL
AND a.result>10
However, the last condition for result doesn't seems to work. It simply lists all the entries from table a, regardless whether result is more than 10 or not.
Any way around this?
Shouldn't your query be as below?
SELECT * FROM a LEFT OUTER JOIN b ON a.id = b.id WHERE b.id IS NULL AND a.result>10

HQL some tables are joined some are not - please explain

I have come across some hql that looks like this:
select a.id
from something a inner join a.whatever b,
somethingelse c inner join c.blah d
where a.id = c.id
Why is a inner joined to b and c inner joined to d but a is linked to c via where
What exactly is this hql saying? Please explain in simple terms.
This query means that the a and b are related in the model. Same is the case with c and d.
In order to join a and c, you have to explicitly state the join field, i.e., id since the model does not have this information.

What would be the correct syntax for a full outer join in linq

I'm new to linq and I'm having trouble getting the correct syntax for this sql statement.
SELECT
A.AssetName,
B.MPercentage,
B.OPercentage,
B.IsStateDefault,
D.ShortName
FROM [Core].[dbo].[Asset] A
FULL OUTER JOIN [Core].[dbo].[PayrollMarkup] B
ON A.PayrollMarkupID = B.PayrollMarkupID
FULL OUTER JOIN [Core].[dbo].[StatePayrollMarkup] C
ON B.PayrollMarkupID = C.PayrollMarkupID
FULL OUTER JOIN [Core].[dbo].[StateLookup] D
ON C.StateID = D.StateID
WHERE A.AssetName IS NOT null

Linq query only returning 1 row

Dim ds = From a In db.Model
Join b In db.1 On a.id Equals b.ID
Join c In db.2 On a.id Equals c.ID
Join d In db.3 On a.id Equals d.ID
Join f In db.4 On a.id Equals f.ID
Select a.id, a.Ref, a.Type, a.etc
Above is my linq query. At the moment I am only getting the first row from the db returned when there are currently 60 rows. Please can you tell me where I am going wrong and how to select all records.
Thanks in advance!
UPDATE:
When I take out all the joins like so:
Dim ds = From a In db.1, b In db.2, c In db.3, d In db.4, f In db.5
Select a.id, a.Ref, a.type, b.etc, c.etc, d.etc
I get a system.outofmemory exception!
You're only going to get a row produced when all of the joins match - in other words, when there's a row from Model with an AP, an Option, a Talk and an Invoice. My guess is that there's only one of those.
LINQ does an inner join by default. If you're looking for a left outer join (i.e. where a particular row may not have an Invoice, or a Talk etc) then you need to use a group join, usually in conjunction with DefaultIfEmpty.
I'm not particularly hot on VB syntax, but this article looks like it's what you're after.

Resources