NativeSql query into JPQL query convertion - spring-data-jpa

I have native query like this
SELECT sample.api_name,
sample.hitcount,
r.unit_rate*sample.hitcount AS amnt
FROM
(SELECT u.api_name AS api_name,u.tenant_id,
u.count AS hitcount
FROM tableA u
WHERE u.tenant_id = :tenant
AND u.time_stamp BETWEEN :dateFrom AND :dateTo
GROUP BY u.api_name,
u.tenant_id) AS sample
LEFT JOIN tableB r ON sample.api_name = r.api_name
AND sample.tenant_id =r.tenant_id
The values "tenant,dateFrom,dateTo" values are providing by using #Param tag.
I have tried to convert to the jpql query in spring data jpa.
But by seeing in some reference documents i came to know that the
Jpql inner queries are not supported in the FROM clause.
is that my point correct or not. If not Please help me to write in JPQL if my point is correct please help to write in Criteria api.

Related

Subquery in FROM clause using CriteriaQuery

I need to implement select from a nested query, for the sake of simplicity let it be:
select * from (select * from city) c
How can this be done using CriteriaQuery and Subquery?
You can't because (select * from city) is not an entity and CritieriaAPI queries on entities not on tables.
The only way would be to create a view for (select * from city) and map that view to an entity.
First, your syntax is not JPA compliant as mentioned previously, secondly, you must know that subqueries in JPQL are allowed only in WHERE and HAVING clauses. The same applies to Criteria queries. If you need the more powerful SQL subquery features then with JPA you have to use JPA provisions for native queries, or otherwise, use another type of JDBC library.

(JPA) Append condition in ON clause during Joins

I need the JPQL in this format:
SELECT *
FROM Person p
LEFT JOIN Address a ON p.id = a.id AND a.flat = 100;
But when i run the code the query being slightly modified henceforth the output of data changed..
SELECT * FROM Person p LEFT JOIN Address a ON p.id = a.id where a.flat = 100;
I suppose you want to format the sql output.
So for hibernate, you can set hibernate.format_sql=true to well format the sql.
If you are using spring boot, you can config it via spring.jpa.properties.hibernate.format_sql=true simply.
JPQL does not allow joining to arbitrary other root objects, so you can't do that in JPQL; only allowing you to join along relations. Individual vendors may offer a vendor extension to allow joining across arbitrary roots but you then lose portability.
To provide more than that you have to post the actual JPA entities, and you haven't.

Spring Data JPA subquery in from

Spring DATA JPA support subquery in from ?
like
select * from (
select unique_id
from table_a
) as from_a
inner join table_b
on from_a.unique_id = table_b.unique_id
querydsl JPASubquery or Spring DATA criteria impossible?
I think it is noe possible.
in other way. you use JPAExpressions. it will be serching for subquery in query dsl.
But i aleardy user that subQuery that are result only one table.

JPA - MAX of COUNT or SELECT FROM SELECT

I wrote the following query for MySQL:
SELECT subquery.t1_column1,
subquery.t2_id,
MAX(subquery.val)
FROM (
SELECT t1.column1 as t1_column1,
t1.id_t2 AS t2_id,
count(1) AS val
FROM table1 t1
INNER JOIN table2 t2
ON t2.id = t1.id_t2
GROUP BY t1.id_t2
) subquery
GROUP BY t1_column1
And I'd like to translate it into JPA (JPQL or criteria query).
I don't know how to make this max(count) thing, and JPA doesn't seem to like the SELECT FROM SELECT...
If anyone has an idea other than native queries (I'll do it for now), it would be great.
I haven't checked tha JPA specification, but given that the Hibernate documentation says
Note that HQL subqueries can occur only in the select or where
clauses.
I very much doubt that your query can be transformed in a valid JPQL query.
You'll have to keep using this native SQL query.
JPA 2.0 JPQL does not support sub-selects in the from clause. You may want to try to rewrite your query, or use a native SQL query.
EclipseLink 2.4 will support sub-selects in the FROM clause,
see,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Sub-selects_in_FROM_clause

DB2 Query Structure Using User-Defined Function as a Table

I'm a little new to DB2, and am having trouble developing a query. I have created a user-defined function that returns a table of data which I want to then join and select from in larger select statement. I'm working on a sensitive db, so the query below isn't what I'm literally running, but it's almost exactly like it (without the other 10 joins I have to do lol).
select
A.customerId,
A.firstname,
A.lastname,
B.orderId,
B.orderDate,
F.currentLocationDate,
F.currentLocation
from
customer A
INNER JOIN order B
on A.customerId = B.customerId
INNER JOIN table(getShippingHistory(B.customerId)) as F
on B.orderId = F.orderId
where B.orderId = 35
This works great if I run this query without the where clause (or some other where clause that doesn't check for an ID). When I include the where clause, I get the following error:
Error during Prepare 58004(-901)[IBM][CLI Driver][DB2/LINUXX8664]
SQL0901N The SQL statement failed because of a non-severe system
error. Subsequent SQL statements can be processed. (Reason "Bad Plan;
Unresolved QNC found".) SQLSTATE=58004
I have tracked the issue down to fact that I'm using one of join criteria for the parameters (B.customerId). I have validated this fact by replacing B.customerId with a valid customerId, and the query works great. Problem is, I don't know the customerId when calling this query. I know only the orderId (in this example).
Any thoughts on how to restructure this so I can make only 1 call to get all the info? I know the plan is the problem b/c the customerId isn't getting resolved before the function is called.
So if I understand correctly, the function getShippingHistory(customerId) returns a table.
And if you call it with a single customer Id that table gets joined in your query above no problem at all.
But the way you have the query written above, you are asking db2 to call the function for every row returned by your query (i.e. every b.customerId that matches your join and where conditions).
So I'm not sure what behaviour you are expecting, because what you're asking for is a table back for every row in your query, and db2 (nor I) can figure out what the result is supposed to look like.
So in terms of restructuring your query, think about how you can change the getShippingHistory logic when multiple customer Ids are involved.
i found the best solution (given the current query structure) is to use a LEFT join instead of an INNER join in order force the LEFT part of the join to happen which will resolve the customerId to a value by the time it gets to the function call.
select
A.customerId,
A.firstname,
A.lastname,
B.orderId,
B.orderDate,
F.currentLocationDate,
F.currentLocation
from
customer A
INNER JOIN order B
on A.customerId = B.customerId
LEFT JOIN table(getShippingHistory(B.customerId)) as F
on B.orderId = F.orderId
where B.orderId = 35