I have formulated an SQL query that I need to translate into JPQL. The query contains a subquery in the SELECT clause, and also selects all rows from the same table that is contained in the subquery.
The following is an example of the SQL query that I am trying to translate:
SELECT table.* FROM TABLE table, (SELECT * FROM TABLE table1 WHERE ... ) table1 WHERE table.id >= table1.id
The part that I am having difficulties with is the table that I am creating using the subquery SELECT table.* FROM TABLE table, (SELECT * FROM TABLE table1 WHERE ... ) table1. The WHERE clause in the subquery is clear how to translate.
The way I currently have tried to translate the query is:
SELECT t FROM Table t, t1 FROM Table t1 WHERE ... WHERE t.id >= t1.id
The error I am getting when trying this is:
org.eclipse.persistence.jpa.jpql.parser.NullExpression cannot be cast to org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable
Any help or suggestions would be appreciated :D
Well.... I guess I found the answer. It's not possible to implement such named queries as explained in this post: JPA/hibernate subquery in from clause
I will stick to a native query instead.
Related
I'm not sur why my SQL query works fine on Oracle console, but not with HQL.
Here's the query as I run it in my Oracle console :
select distinct table1.*
from TABLE1 table1, TABLE2 table2
where table1.ID in (
select max(table2.RID_TABLE2) from TABLE2 table2 group by RID_OBJECT
);
This query returns 5 rows, and for some reason, the exact same query in HQL returns 6 rows.
Here is the HQL query:
#Query(name = "select distinct table1.*
from TABLE1 table1, TABLE2 table2
where table1.ID in (
select max(table2.RID_TABLE2) from TABLE2 table2 group by RID_OBJECT
)")
Set<Object> findTable1ByTable2();
From what I've seen here, it might be related to the fact that I use a subquery in my where clause, and it seems like HQL queries do not allow it.
Basically, it seems like the following part of my 'where' my query is simply ignored with HQL table1.ID in (select max(table2.RID_TABLE2) from TABLE2 table2 group by RID_OBJECT).
My goal is to have both my SQL and HQL queries return 5 rows.
Is there a solution to this ?
I have a rather simple query that works in standard SQL, but doesn't in HQL :
SELECT id
FROM ( SELECT COUNT(*) as rows,
MESSAGES_ID as id
FROM motcles_message mm
WHERE motcle IN :keyWords
GROUP BY MESSAGES_ID) a
WHERE a.rows = :size
Is there any way for me to avoid using a subquery in the FROM statement since HQL doesn't support it ?
I know it can use subqueries in SELECT and WHERE clauses, but I can't find a solution.
SELECT MESSAGES_ID as id
FROM motcles_message mm
WHERE motcle IN :keyWords
GROUP BY MESSAGES_ID
HAVING COUNT(*) = :size
I am using an insert into select mysql query, but in the select statement I am passing a parameter(map) from Java. This query is written using iBatis framework. The query is not recognizing the passed value in the select statement.
I have tried changing #id# to
#{id}, $id$, #{id} and ${id} but didn't succeed.
The query goes like this:
<insert id="someId" parameterClass="map" >
insert into table1(id, column1, column2)
(
select #id#, A.column1, A.column2
from table2 A left outer join table3 B on A.column = B.column
where <condition>
order by column1, column2
)
</insert>
I have sent the request parameter as a 13-digit long id.
In the table1 schema, id has bigint(20) as its datatype.
I want whatever parameter(id) I am passing to the query to be inserted in the table.
Now the problem is that it is not recognizing the value of #id#.
As the id column constraint is not null, it is throwing "MySQLIntegrityConstraintViolationException: Column 'id' cannot be null" after running the above statement.
What should I try instead of #id# to get it working? Or could it be some other problem?
In MyBatis, a #{param} parameter is a "safe" parameter than can only replace scalar values. For safety it cannot be used to add any free content to your SQL statement so you can forget about SQL Injection issues. Even if you try the nastier parameter values you can think of, you'll still be safe and you'll sleep well at night.
Now, if you want to insert any arbitrary content to your SQL (to produce some kind of dynamic SQL) and risk sleepless nights MyBatis offers you ${param} parameters (did you spot the difference?). These string parameters are directly inserted into your SQL statement. With this strategy your query should look like:
<insert id="someId" parameterClass="map" >
insert into table1(id, column1, column2)
(
select ${id}, A.column1, A.column2
from table2 A left outer join table3 B on A.column = B.column
where <condition>
order by column1, column2
)
</insert>
Now, please note this strategy is vulnerable to SQL Injection when not managed appropriately. Make sure the value for the id parameter comes from inside your app and NEVER retrieved from the web page or other external user interface or app.
I have an many to many table which I am querying and want to return one column from it
Consider
Table 1
M to M (consisting of TABLE1_ID and TABLE2_ID)
Table2
I am in Table 2 entity and I want to return all the table 2 ids in the M to M table when I give it a table 1 id.
In my entity I have
#ElementCollection
#CollectionTable(name="M_TO_M_TABLE", joinColumns=#JoinColumn(name="TABLE1_ID"))
#Column(name="TABLE_2_ID")
private Set<Integer> tableTwoIds;
When I try and query this the JPA query that is produced is weird!
My query is
SELECT tab2 from Table2 tab2 where tab2.tableOneIds in (:idsPassedIn)
The error I get makes sense from the query that is generated. The error is
org.hibernate.exception.GenericJDBCException: Missing IN or OUT parameter at index:: 1
and the query is
select tab2.ID, tab2.NOTES
from TABLE_2 tab2, M_TO_M mToM
where tab1.ID=mToM.TAB_1_ID and (. in (? , ?))
and we have a . after the and rather than mToM.TAB_2_ID
Has anyone any ideas?
Thanks
I would like to execute this SQL request in QueryDSL JPA
SELECT authorizationitem.*
FROM authorizationitem
INNER JOIN
(
SELECT `authorize`
FROM authorizationitem
GROUP BY `authorize`
HAVING COUNT(*)>1
) a2
ON authorizationitem.`authorize` = a2.`authorize`;
in order to find duplicated row in a table, i should execute this request. But with QueryDSL, i cannot find the way to write this.
It seems QueryDSL does not allow subQuery in Inner Join :s
Any suggestion?
Thanks
regards,
You can't express this with HQL/JPQL, so you will need to expess this with SQL. Querydsl JPA provides the possibility to express both JPQL and SQL queries through its API.
You can try using a subquery in the WHERE clause, but it will probably be less efficient than the subquery in the FROM clause. Make sure there is an index on authorizationitem.authorize to optimize the joins and the GROUP BY.
SELECT authorizationitem.*
FROM authorizationitem
WHERE EXISTS (
SELECT `authorize`
FROM authorizationitem2
WHERE authorizationitem2.authorize = authorizationitem.authorize
GROUP BY `authorize`
HAVING COUNT(*)>1
);
or
SELECT authorizationitem.*
FROM authorizationitem
WHERE (
SELECT count(*)
FROM authorizationitem2
WHERE authorizationitem2.authorize = authorizationitem.authorize
GROUP BY `authorize`
) > 1;