combining QueryOver and CreateQuery subquery - nhibernate

I'm using QueryOver<> to execute a series of subqueries using a conjunction. Here is some psuedo code that explains what I'm doing:
Conjunction conj = new Conjunction();
conj.Add(Subqueries.WhereProperty<Customer>(...).In(QueryOver.Of<Foo>().Where(...));
conj.Add(Subqueries.WhereProperty<Customer>(...).In(QueryOver.Of<Bar>().Where(...));
var result = session.QueryOver<Customer>()
.Where(conj)
.List();
This works fine but I've come across a scenario where I need to use HQL (CreateQuery()) for one of my subqueries. The reason I need to use HQL is because I need a theta (aka cross) join due to an unmapped relationship (unfortunately I can't change this).
Is there a way I can use CreateQuery() (or CreateCriteria() assuming I can do theta joins) to define subqueries and specify the top level query using QueryOver<>()?

No, HQL queries and QueryOver / Criteria queries cannot be combined.
You can use plain SQL in QueryOver / Criteria.

Related

Converting Postgre to Bigquery

I am having a trouble with a conversion from Postgre to Bigquery query.
Please, how could this query work on bigquery ? I need to subselect a table and bring the last register
(select g.fase__c
from operacoes.salesforce_gest_o_do_canal_c_full g
where g.n_de_indentifica_o_do_parceiro__c = a.n_de_indentifica_o_do_parceiro__c
order by g.data_do_credenciamento__c limit 1) as fase_jornada
from operacoes.salesforce_account_full
If I try to execute, Bigquery returns an error I should apply a join, If I apply the join, the order by doesn´t work
Thanks!
A correlated subquery (which is a subquery that references a table of an outer query), if executed "as is", would need to compute the subquery for each row of the results of the outer query, which would not be very efficient.
In order to optimize this, BigQuery first transforms (decorrelates) the query into one that is functionally equivalent to the correlated one but without any correlations between queries and subqueries. Different decorrelation processes are needed for different use cases and they can be quite complex and difficult to implement and properly test.
BigQuery is implementing decorrelation strategies to make a variety of correlated subqueries possible, however decorrelation for the LIMIT clause has not been implemented.
A workaround would be to use ARRAY_AGG instead of a subquery. In your case, I believe the following query would do the work:
SELECT
ARRAY_AGG(g.fase__c
ORDER BY g.data_do_credenciamento__c
LIMIT 1) AS fase_jornada
FROM
operacoes.salesforce_account_full a
JOIN
operacoes.salesforce_gest_o_do_canal_c_full g
ON
g.n_de_indentifica_o_do_parceiro__c = a.n_de_indentifica_o_do_parceiro__c
GROUP BY
g.n_de_indentifica_o_do_parceiro__c
Take into account that I have guessed some details since the whole context for the subquery was not provided, so you may need to make some changes to it.
Please let me know if anything was not clear!

Hibernate: Oracle join with (+) on independent tables

Basically here's the prob:
I can't change existing queries with "(+)" joins
I need to use Hibernate.
I can't put an association between these independent tables.
What I got so far is to use
entityMgr.createNativeQuery("my join (+) query here");
I then store it in a generic
List<Object> list = query.getResultList()
And get column values via
for(Object obj: list) {
firstColVal = obj[1]
...
}
Question: Is this the best option I've got? Are there better solutions?
Edit: You guys can suggest a more fitting ORM framework than Hibernate :)
The oracle join operation that you can not remove from your query is deprecated as it was introduced before ANSI standard.
That operator is different from typical join, but the main difference is that you can do less with it then with ANSI notation.
A solution for you might be to create a view on database that will be mapped in code. But your solution is still valid. You can additionally add a result transformer, that will produce valid tuple for result.

specify Index hint in HQL

I need to specify a Index hint for my HQL
Query.setComment()
method is of no use as it is appending the hint before the select clause,
though this can be achieved by NativeSQL but I just wanted to check is there a way we can achieve this in HQL rather then SQL
As per My understanding there is no support for specifying index hints in HQL currently as of version 3.6.5
though this can be achieved by specifying #NamedNativeQueries or by calling CreateSQLQuery() on query interface
You can find a technique I use to specify Query Hints here, you can adapt this to insert some custom SQL inside some specific HQL or ICriteria query.
In my example I'm only interested in adding OPTION (RECOMPILE) or OPTION (HASH JOIN) but the technique comments<->interceptor can be used to manipulate the generate SQL in any way.

NHibernate problem choosing between CreateSql and CreateCriteria

I have a very silly doubt in NHibernate. There are two or three entities of which two are related and one is not related to other two entities. I have to fetch some selected columns from these three tables by joining them. Is it a good idea to use session.CreateSql() or we have to use session.CreateCriteria(). I am really confused here as I could not write the Criteria queries here and forced to use CreateSql. Please advise.
in general you should avoid writing SQL whenever possible;
one of the advantages of using an ORM is that it's implementation-agnostic.
that means that you don't know (and don't care) what the underlying database is, and you can actually switch DB providers or tweak with the DB structure very easily.
If you write your own SQL statements you run the risk of them not working on other providers, and also you have to maintain them yourself (for example- if you change the name of the underlying column for the Id property from 'Id' to 'Employee_Id', you'd have to change your SQL query, whereas with Criteria no change would be necessary).
Having said that- there's nothing stopping you from writing a Criteria / HQL that pulls data from more than one table. for example (with HQL):
select emp.Id, dep.Name, po.Id
from Employee emp, Department dep, Posts po
where emp.Name like 'snake' //etc...
There are multiple ways to make queries with NH.
HQL, the classic way, a powerful object oriented query language. Disadvantage: appears in strings in the code (actually: there is no editor support).
Criteria, a classic way to create dynamic queries without string manipulations. Disadvantages: not as powerful as HQL and not as typesafe as its successors.
QueryOver, a successor of Criteria, which has a nicer syntax and is more type safe.
LINQ, now based on HQL, is more integrated then HQL and typesafe and generally a matter of taste.
SQL as a fallback for cases where you need something you can't get the object oriented way.
I would recommend HQL or LINQ for regular queries, QueryOver (resp. Criteria) for dynamic queries and SQL only if there isn't any other way.
To answer your specific problem, which I don't know: If all information you need for the query is available in the object oriented model, you should be able to solve it by the use of HQL.

how to do WHERE a*b = param1 in NHibernate

I need to create a query in NHibernate that would search for a product of two columns, like this:
WHERE a*b = param1
leaving efficiency aside (assume I have little rows or actual query will have extra conditions that will exploit some indexes) how do I do it in NHibernate? Preferably the solution should work with DetachedCriteria. I know I could use native SQL with Expression.Sql() but is there any other, better, way? Can I do this in HQL?
You can do this with HQL or Expression.Sql as you mentioned. HQL supports many different SQL expressions; see this section.
For example:
session.CreateQuery("from test t where t.a * t.b = 4").List();