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.
Related
I'm trying to write a QueryDSL expression for selecting a column value. It's a few joins away from the 'from' table:
a.b.c.get(0).field
where b may be null object, but if not then it will have at most 1 record in c collection.
what I want is something like
new CaseBuilder()
.when(a.b.isNotNull().and(a.b.c.isNotEmpty()))
.then(a.b.c.get(0).field.stringValue())
.otherwise(Expressions.stringTemplate("''"))
This implicitly produces inner joins with b and c tables in SQL, which is not what I want because that returns no results when b is in fact null. Adding explicit left outer joins doesn't stop the implicit joins anyway. I'm pretty sure I'm not thinking about this the right way, please help me get unstuck :-)
When I had added support for implicit joins to jOOQ, I had researched the topic and stumbled upon this "limitation" / design in Hibernate as well. I've reported this issue to the Hibernate-dev mailing list recently as I clearly think this is a bug:
http://lists.jboss.org/pipermail/hibernate-dev/2018-February/017299.html
I don't see why any projection expression should "inadvertently" produce a filter on the FROM clause. This appears to be quite contrary to the intuition that one might build when thinking in terms of relational algebra.
You can read the replies to that email, particularly this rationale by Steve Ebersole:
I was saying that I can no longer look at the
HQL/JPQL and tell what kind of SQL joins will be used for that if it is
dependent on the mapped association. This approach was mentioned earlier
in the thread. But you clarified that you mean that implicit joins ought
to just always be interpreted as an outer join.
You could plugin in your own query handling and interpret implicit joins
however you want. That is current not the most trivial task though.
I don't think this will get fixed any time soon in Hibernate. So, the workaround here is to build all of your outer joins explicitly and not use any implicit joins whenever you expect them to produce outer joins.
one more problem. I need your help.
Make a list of medications that have been entered as the same (identical_with) but differ in their association with the disease.
identical_with
association
I don't know how to do that.
The result should be in that case:
result
To solve your problem, you need to use twice the table association. Following code should be OK:
select
i.Name_1, i.Name_2
from
association a
inner join
identical_with i
on i.Name_1 = a.Name
inner join
association a2
on i.Name_2 = a2.Name
where
a2.Fachname <> a1.Fachname
This is a bit long for a comment, although the answer is essentially "you can't do this in MySQL".
The support you are looking for is for hierarchical or recursive queries. Almost every databases except MySQL has built-in support for these types of queries. This leaves you with essentially four choices:
Switch to using a database that has such support. Among free databases, these include Postgres, SQL Server Express, and Oracle Express.
If you limit the depth of equivalence, you can use repeated self joins.
You can do this with a while loop in a stored procedure. However, that is not a single SQL statement.
Use a nested set model
Use a method where you store the full path.
Unfortunately, the last two methods require triggers to maintain the data structure of inserts, updates, and deletes.
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.
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.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Is there something wrong with joins that don't use the JOIN keyword in SQL or MySQL?
Hi,
i'ave always retrieved data without joins...
but is there a benefit to one method over the other?
select * from a INNER JOIN b on a.a = b.b;
select a.*,b.* from a,b where a.a = b.b;
Thanks!
The first method using the INNER JOIN keyword is:
ANSI SQL standard
much cleaner and more expressive
Therefore, I always cringe when I see the second option used - it just bloats up your WHERE clause, and you can't really see at one glance how the tables are joined (on what fields).
Should you happen to forget one of the JOIN conditions in a long list of WHERE clause expressions, you suddenly get a messy cartesian product..... can't do that with the INNER JOIN keyword (you must express what field(s) to join on).
I'd say the biggest benefit is readability. The version with the explicitly named join types are much easier for me to comprehend.
You are using a different syntax for a JOIN, basically. As a matter of best practices, it is best to use the first syntax (explicit JOIN) because it is clearer what the intention of the query is and makes the code easier to maintain.
These are both joins. they are just two different syntactical representations for joins. The first one, (using the "Join" keyword, is the current ANSI Standard (as of 1992 I think).
In the case of inner joins only, the two differeent representations are functionally identical, but the latter ANSI SQL92 standard syntax is much moire readable, once you get used to it, because each individual join condition is associated with the pair of intermediate resultsets being joined together, In the older representation, the join conditions are all together, along with the overall queries' filter conditions, in the where clause, and it is not as clear which is which. This makes identifying bad join conditions (where for example, an unintended cartesian product will be generated) much more difficult.
But more important, perhaps, is that, when performing an outer Join, in certain scenarios, the older syntax is NOT equivilent, and in fact will generate the WRONG resultset.
You should transition to the newer syntax for all your queries.
You've always retrieved the data with joins. The second query is using old syntax, but in the background it is still join :)
This depends on the RDBMS but in the case of SQL server I understand that the utilizing the former syntax allows for better optimization. This is less of a SQL question and more of a vendor specific question.
You can also use the EXPLAIN (SQL Server: Query Execution Plan) type functions to help you understand if there is a difference. Each query is unique and I imagine that the stored statistics can (and will) alter the behavior.