Find duplicated rows in MySQL with QueryDSL JPA - java

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;

Related

How to avoid subquery in FROM clause to translate SQL query into hibernate query?

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

Update using join or nasted sub-query Hibernate (HQL)

I have a problem creating HQL that updates entity CommitteeMembership with nested queries or using joins, i tried this query first:
update CommitteeMemberShip cms set cms.isDeleted=1
where cms.committeeCycle.committee.id=:committeeId
but the generated SQL was wrong as following:
update CommitteeMemberShip cross join set isDeleted=1 where committee_id=?
without any this after "cross join" makes Hibernate throws SQLGrammarException
After that, i have changed my query to use sub-query:
update CommitteeMemberShip cms set cms.isDeleted=1
where cms.id in (select cmsIn.id from CommitteeMemberShip cmsIn inner join
cmsIn.committeeCycle cc inner join cc.committee c where c.id=:committeeId)
now Hibernate throws
java.sql.SQLException: You can't specify target table 'CommitteeMemberShip' for
update in FROM clause
any one have any idea how i can write this update query in HQL??
Try this
update CommitteeMemberShip cms set cms.isDeleted=1
where cms.id = some(select cmsIn.id from CommitteeMemberShip cmsIn inner join
cmsIn.committeeCycle cc inner join cc.committee c where c.id=:committeeId)
Try this
"UPDATE table1 r SET r.column = #value WHERE r.column IN("SELECT rd.Id FROM r.table2 rd WHERE rd.Column='"+#value+"' AND rd.Column='"+value+"'";
It seems that HQL does not yet support path expressions / implicit joins in DML statements. Here's how jOOQ does it (in SQL, assuming all paths are to-one relationships (Disclaimer: I work for the company behind jOOQ)):
UPDATE CommitteeMemberShip cms
SET cms.isDeleted = 1
WHERE (
SELECT Committee.id
FROM Committee
WHERE (
SELECT CommitteeCycle.committeeId
FROM CommitteeCycle
WHERE CommitteeCycle.id = cms.committeeCycleId
) = Committee.id
) = :committeeId
Your own approach didn't work because you repeated the CommitteeMemberShip entity unnecessarily. That's a known MySQL limitation, see:
MySQL Error 1093 - Can't specify target table for update in FROM clause
This would have worked, I suspect?
UPDATE CommitteeMemberShip cms
SET cms.isDeleted = 1
WHERE cms.committeeCycleId IN (
SELECT CommitteeCycle.id
FROM CommitteeCycle cc
JOIN cc.committee c
WHERE c.id = :committeeId
)
Starting with Hibernate 6 and their support for derived tables, you might be able to work around MySQL's limitation like this (the same way as jOOQ does it out of the box, see here):
UPDATE CommitteeMemberShip cms
SET cms.isDeleted=1
WHERE cms.id IN (
-- Wrap the query once more in a derived table
SELECT t.id
FROM (
SELECT cmsIn.id
FROM CommitteeMemberShip cmsIn
JOIN cmsIn.committeeCycle cc
JOIN cc.committee c WHERE c.id=:committeeId
) t
)

convert sql to hql

I am performing this via sql but i want to do this in hql, select statement in from ( select count(*)...) not works in hql, any sugestion and optimization would be appreciated
SELECT u.username,u.device_tocken,sr.count
from users u,
(select count(*) as count ,ssr.recepient as res from survey_recipient ssr where
(ssr.is_read is false and ssr.recepient in ('abc','xyz'))group by ssr.recepient ) sr
where
(u.username = sr.res and u.device_tocken is not null)
Hibernate does not support subselects in from clouse.
i tried many things and gave up when i found this jira issue.
see here https://hibernate.onjira.com/browse/HHH-3356
But if you have to use subselect you can create database views and use them in your sql as normal tables.

How to write complex join query with JPA

How to write this kind of complex join query with JPA, Some of syntax I have denoted below not work with JPA. I have used them for demonstrate way that sql query should build, so sorry about that.
SELECT Result1.name1, Result1.count1, Result2.name2, Result2.count2 FROM (
SELECT
taskOne.user.name AS name1,
COUNT(taskOne.taskId) AS count1
FROM
Task AS taskOne
INNER JOIN
taskOne.defect AS defectOne
WHERE (
defectOne.defId = taskOne.defect.defId
AND
taskOne.taskCategory.tcaId = 1
)
GROUP BY
taskOne.user.usId
) AS Result1
FULL JOIN (
SELECT
taskTwo.user.name AS name2,
COUNT(taskTwo.taskId) AS count2
FROM Task AS taskTwo
INNER JOIN taskTwo.defect AS defectTwo
WHERE (
defectTwo.defId = taskTwo.defect.defId
AND
taskTwo.taskCategory.tcaId = 2
)
GROUP BY taskTwo.user.usId
)
AS Result12
WHERE Result1.name1 = Result12.name2
JPQL is desired for selecting objects. Your query seems incredibly complex, I would recommend a native SQL query, or simplifying it.
JPQL does not support sub selects in the from clause.

Hibernate - cant use GROUP BY With ORDER BY together

This one is odd...
I have an hql query that ignore the GOUP BY if ORDER BY is included.
it will perform the query without the group by,
but if I remove the order by it will work fine
list = getSession().createQuery(
"SELECT
Brand.name as Brand_name
, Brand.url as Brand_url
, Brand.email as Brand_email
, Brand.brandId as Brand_brandId
, Brand.description as Brand_description
FROM com.affiliates.hibernate.Brand Brand
INNER JOIN Brand.users as users
WHERE 1=1
AND users.userId>'0'
order by Brand.email ASC
group by brandId"//this one will be ignored because of the order by
).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
sql generated:
select
brand0_.NAME as col_0_0_,
brand0_.URL as col_1_0_,
brand0_.EMAIL as col_2_0_,
brand0_.DESCRIPTION as col_3_0_
from
BRAND brand0_
inner join
USERS_BRANDS users1_
on brand0_.BRAND_ID=users1_.BRAND_ID
inner join
USER user2_
on users1_.USER_ID=user2_.USER_ID
where
1=1
and user2_.USER_ID>'0'
order by
brand0_.EMAIL ASC limit ?
First, notice that BRAND.BRAND_ID has been drop from the column projections in the SQL. This is probably related to the group by being dropped as well.
Second, notice there are no aggregate functions defined in the query. Group only works on aggregations. Try adding an aggregate function, such as max, to all of the columns. This might be the cause of the problem
Last, try fully qualifying brandId in the HQL to eliminate any confusion:
group by Brand.brandId
You should apply orderby after groupby but you have written as
order by Brand.email ASC
group by brandId"//this one will be ignored because of the order by
).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
But Change to:
group by brandId"//this one will be ignored because of the order by
).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
order by Brand.email ASC
Then it will work

Categories

Resources