NHibernate HQL subselect left join? - nhibernate

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

Related

HQL Join not working

I got a problem with a quiet simple join statement.
There is a table A and another table B. Table A has an idNumber.
Table B has got an number.
Now I want to join this tables on idNumber=number
What I do is:-
A.executeQuery("Select a from A a inner JOIN B b ON a.idNumber=b.number")
Unfortunately, I get an empty list as result but that is wrong.
Anyone has an idea what I am doing wrong?
It seems you are running a sql query. So for running sql query, you need to define which columns you are selecting.
A.executeQuery("Select a.* from A a inner JOIN B b ON a.idNumber=b.number") // don't forget * after a
PS. For hql query I need to know your class structure.
Hibernate Query Language (HQL) is an object-oriented query language, similar to SQL, but instead of operating on tables and columns, HQL works with persistent objects and their properties.
Let's assume class A has an instance of B. Then JOIN query will be as following.
Select a from A a inner JOIN a.B
A has an instance of B. B is in the package a.package.name
I just tried
A.executeQuery("Select a from A a inner JOIN a.package.name.B b where a.idNumber=b.number")
The Problem was that one Table was in an extern Plugin and it was not possible to join them here. I had to do two requests.

Need Input | SQL Dynamic Query

Have a requirement where I need to build a dynamic query based on user input and send the count of records from result set.
So there are 6 tables which I needs to make a join Inner for sure and rest table join will be based on user input and this should be performance oriented.
Here is the requirement
select count(A.A1) from table A
INNER JOIN table B on B.B1=A.A1
INNER JOIN table B on C.C1=B.B1
INNER JOIN table D on D.D1=C.C1
INNER JOIN table E on E.E1=D.D1
INNER JOIN table F on F.F1=E.E1
Now if user select some value in UI , then have to execute query as
select count(A.A1) from table A
INNER JOIN table B on B.B1=A.A1
INNER JOIN table B on C.C1=B.B1
INNER JOIN table D on D.D1=C.C1
INNER JOIN table E on E.E1=D.D1
INNER JOIN table F on F.F1=E.E1
INNER JOIN table B on G.G1=F.F1
Where G.Name like '%Germany%'
User can send 1- 5 choices and have to build the query and accordingly and send the result set
So if I add all the joins first and then add where clause as per the choice , then query will be easy and serve the purpose, but if user did not select any query then I am creating unnecessary join for the user choices.
So which will be better way to write having all the joins in advance and then filtering it or on demand join and with filters using dynamic query.
Could be great if someone can provide valuable inputs.
When SQL Server executes a query, there is a first step which is planning the query, i.e. deciding an strategy to get the query result.
If you use "inner joins" you're making it compulsory to include all the tables, becasuse "inner join" means that there must be matching rows on both tables of the join, so the query planner can't dicard any tables.
However, if you change the inner joins by left outer joins, it's not compulsory that there are matching rows on both sides of the join, so the query planner can decide if it includes or not the tables on the right. So, if you use left outer joins, and you don't select, or filter, or do any operation on fields on the right side of the joins, the query planner can discard then when executing the query. That's the easiest way to get rid of your concerns.
On the other hand, if you want to control what tables to inclued or not to include, and create a custom query for each case, you can use several techniques:
making a graph that includes the definition of the table relations, and using some graph manipulation library that allows you to get the necessary tables from the graph.I did this one, but is quite hard to achieve if you don't have experience with graps.
using Entity Framework. You must build a simple model including all the tables. And then, to run each query, you can programmatically build the query in LINQ, and EF will take care to generate and execute the SQL query for you.

DQL LEFT JOIN - sql example

well-functioning SQL is:
SELECT ro.id_role
,rr.id_role_resource
,re.id_resource
FROM resource re
LEFT JOIN role_resource rr
ON rr.resource_id = re.id_resource
LEFT JOIN role ro
ON ro.id_role = rr.role_id
now I must write DQL-
this is table shema:
role: id_role, name
role_resource: id_role_resource, role_id, resource_id, permission
resource: id_resource, controller,action ...
in the last table are no corresponding records in the table role_resource.
That's why i need this left Join Query in DQL.
Normally if you would have an Resource entity with a $roles property and the correct annotations (OneToMany, ManyToMany) then your join table (role_resource) would not have or need and auto_increment id of its own.
This is because Doctrine handles association information and knows when a join table is needed based on them. Doctrine also knows what conditions to use when joining two entities based on the same association information.
So if an SQL query would join two tables via a third table by using 2 join clauses, a DQL query would only need to be told the association name and it would have all "join table" & "join conditions" information available.
So a simple query would look like:
SELECT
/* i assume $idRole is the name of the property
* mapped to the id_role column
*/
ro.idRole,
/* i assume $idResource is the name of the property
* mapped to the id_resource column
*/
re.idResource
FROM YourNamespace\Resource re
JOIN re.roles
With equivalent queryBuilder syntax:
$this->getEntityManager()->createQueryBuilder()
->select(array('ro.idRole', 're.idResource'))
->from('YourNamespace\Resource', 're')
->join('re.roles');
But JOIN defaults to an INNER JOIN so we would want to fix this by rewriting the query as:
SELECT ro.idRole,
re.idResource
FROM YourNamespace\Resource re
LEFT JOIN re.roles
With equivalent queryBuilder syntax:
$this->getEntityManager()->createQueryBuilder()
->select(array('ro.idRole', 're.idResource'))
->from('YourNamespace\Resource', 're')
->leftJoin('re.roles');
If however you want the role_resource table to have an auto_increment id of its own and be accessible in Doctrine queries, then Doctrine needs to know about that table -- it needs to be mapped to a separate entity and you need to explicitate the fact that you're joining Resources, RoleResources and Roles.

How to convert full outer join query to O-R query?

I'm converting relational database into object-relational in Oracle.
I have a query that uses full outer join in the old one.
Is it possible to write the same query for O-R database without explicitly using full outer join?
For normal inner join it simple, I just use dot notation together with ref/deref.
I'm interested in this in general so let's say the relational query is:
select a.attr, b.attr from a full outer join b on (a.fk = b.pk);
I want to know if it's a good idea to do it this way:
select a.attr, b.attr from a_obj a full outer join b_obj b on (a.b_ref = ref(b));
Say I have the entities 'sale history' and 'sale forecast'. For a given product and period, I want to see the actual sale versus the forecast sale. However any given period may not have had a forecast or an actual sale, so I use an SQL like :
SELECT NVL(f.product_id, h.product_id), NVL(f.period, h.period),
f.forecast_sale, h.actual_sale
FROM forecast f
FULL OUTER JOIN history h ON h.product_id = f.product_id and h.period = f.period
Basically I am joining two child tables together on a common key. Full outer joins are rare in relational databases as normalisation would generally merge the entities with common keys. Left and right outer joins are more common as the typical use case is to select the parent and its children while requiring a row even if a parent has no children.
So if you have a full outer join, the first thing to examine is whether the data structure is correct.
The data structure in an object model is fixed or 'pre-joined'. If the data structures within the model don't readily support the production of a certain result set, then you pretty much have to go without (or at least code up a lot of functionality to extract and join the data manually).
If you post some details about the relevant data structures the advice may be more precise.

NHibernate HQL Join Not Returning All Required Rows

I am modifying an existing HQL query which returns individual columns rather than an object graph but now I am not getting all rows that I need.
Here a few facts about the current schema:
An Estimate belongs to a Contract.
The OwningDepartment property of a Contract can be null.
The ParentBusinessStream property of a Department cannot be null
This is the query:
select e.ID, e.StatusCode.ID, e.InputDate, e.ParentClient.Name, e.ParentContractLocation.ParentLocation.Description, e.Description, e.InternalRef, e.ExternalRef, e.TotalIncTax, e.TaxTotal, e.Closed, e.ViewedByClient, e.HelpdeskRef, e.ParentContract.Reference, d.ParentBusinessStream.Title, d.Name
from Estimate e, Department d where (e.ParentContract.ID in (select cs.ParentContract.ID from ContractStaff cs
where cs.ParentStaff.ID=:staffID)) and ((d.ID = e.ParentContract.OwningDepartment.ID) OR (d.ID is null)) order by e.ID
Unfortunately my query is not returning Estimates where the parent contract does not have an owning department. Instead I want the relevant fields to just be null. I tried a left outer join but got the same results.
Any help would be very much appreciated. Apologies if I've done something stupid.
Cheers,
James
i've found that unusual queries containing left outer joins are better off by using an ISQLQuery which gives you access to proper SQL syntax as well as some HQL power.
Besides that, you don't provide mapping files which usually are helpful
I think I have worked it out: d.ParentBusinessStream.Title is an implicit inner join but since d can be null it doesn't work correctly. I have changed my query to take this into account