Convert sql view query to hql - java

I'm new in Java, so please help if you can.
I need to populate Jtable and I'm doing it with this code:
SELECT r.id AS roomID, r.type, r.no_of_rooms, r.no_of_rooms -
COALESCE(t.bookedRooms,0) AS available_rooms FROM room AS r LEFT JOIN (
SELECT room_id, SUM(total_rooms) AS bookedRooms FROM bookings WHERE
`start` < '2017-02-10' AND `ends` > '2017-02-09' GROUP BY room_id ) AS t
ON r.id = t.room_id WHERE r.no_of_rooms - COALESCE(t.bookedRooms,0) > 0
and it works like this.
But how can I do this with Hibernate and how to do mapping?
Thanks in advance!

Related

Criteria Builder select from select

Can anybody help me to create JPA Criteria Builder query in order to achieve this ?:
select id from (
select distinct r.id
r.date
r.name
from report r
inner join unit u
on u.report_id = r.id
order by
r.date desc,
r.name asc)
where rownum <= 10
I just can create inner query:
CriteriaQuery<Object[]> innerQuery = cb.createQuery(Object[].class);
Root<ReportEntity> root = innerQuery.from(ReportEntity.class);
List<Ojbect[]> resultLsit = em.createQuery(
innerQuery.multiselect(root.get(ReportEntity_.id),
root.get(ReportEntity_.date),
root.get(ReportEntity_.name)
.distinct(true)
.orderBy(cb.desc(root.get(ReportEntity_.date)),
cb.asc(root.get(ReportEntity.name))
).setMaxResults(10).getResultList();
Thx in advance :)
I've decided to get List of Object[] and then retrieve id from array
List idList = resultList.stream().map(array -> (Long)array[0]).collect(Collectors.toList());
This is code smell, but unfortunatelly I haven't found better solution.
Note I use this approach to cope Hibernate issue :
"Warning “firstResult/maxResults specified with collection fetch; applying in memory!”? - this warning pops up due to using fetch and setMaxResults in hql or criteria query.
That's why first of all I get all id, and then I find all entities according this id. (select * from ReportEntity r where r.id in :idList) - smth like this.

JPQL multiple JOIN query

Can someone help me?
I got that SQL query and need to represent that in JPQL, but i faced trouble with right join:
SELECT alrt.*
FROM
REACTION.ALERT alrt, REACTION.INVESTIGATION inv,
REACTION.CLASSIFICATION_TYPE clst, REACTION.FRAUD_TYPE frt,
REACTION.TRANS trns, REACTION.CARD crd
WHERE
alrt.ISS_INST IN(1201, 1101) AND
alrt.MODULE_TYPE = 0 AND
0 < (SELECT COUNT(*) FROM REACTION.INVESTIGATION WHERE REACTION.INVESTIGATION.ALERT_ID = alrt.ID) AND
inv.CLASSIFICATION_TYPE_ID IS NOT NULL AND
clst.CLASSIFICATION_TYPE = 10 AND
(alrt.REMINDER_USER_LOGIN = 'qwr' OR alrt.REMINDER_USER_LOGIN IS NULL) AND
alrt.ID = inv.ALERT_ID AND
alrt.TRANSACTION_ID = trns.ID(+) AND inv.CLASSIFICATION_TYPE_ID =
clst.ID AND inv.FRAUD_TYPE_ID = frt.ID(+) AND trns.HPAN = crd.HPAN(+);
After read tutorials and docs i create that JPQL query:
SELECT alrt
FROM INVESTIGATION inv
JOIN inv.CLASSIFICATION_TYPE_ID clst
RIGHT JOIN inv.FRAUD_TYPE_ID frt
JOIN inv.alert_id alrt
RIGHT JOIN alrt.transactio_id trns
RIGHT JOIN trns.HPAN crd
WHERE
alrt.ISS_INST IN(1201, 1101) AND
alrt.MODULE_TYPE = 0 AND 0 < (SELECT COUNT(inv1) FROM INVESTIGATION inv1 WHERE inv1.ALERT_ID = alrt.ID) AND
inv.CLASSIFICATION_TYPE_ID IS NOT NULL AND
clst.CLASSIFICATION_TYPE = 2 AND
(alrt.REMINDER_USER_LOGIN = 'qwr' OR alrt.REMINDER_USER_LOGIN IS NULL);
But i got error then try to execute that. Can someone tell what i did wrong pls?
If it make sense i use JPA 1.0 version
Your error is join ID, but not OR-mapping object.
Try this:
JOIN inv.CLASSIFICATIONTYPE(your mapping property name) clst
If u do not have mapping relationship between entities, u'd better to user join table i.o. OR-mapping.
Read more information on JPQL

MySQL Select values in table depending on another table

I have a table 'Staff' with details of all Staff. 'StaffID' included.
Then I have a table 'StaffRole' which has 'StaffID' and 'RoleID'
I want to do something like this: Select * From Staff Where RoleID=1;
But I'm not sure if I can do this as RoleID is not in the Staff table.
Anyone know the correct syntax? Any feedback is appreciated.
Try this:
SELECT * FROM staff s
WHERE EXISTS(
SELECT 'ROLE'
FROM staffrole r
WHERE r.staffid = s.staffid
AND r.roleid = 1
)
In alternative:
SELECT * FROM staff s
JOIN staffrole r
ON r.staffid = s.staffid
WHERE r.roleid = 1
Use a join:
select s.*
from staffrole r
join staff s
on s.staffid = r.staffid
where roleid = 1
An index on staffrole(roleid) should make it perform better.

Syntax Error for HQL JOIN Statment

I'm trying to create a HQL query to join a result of a select with another table. What I have currently is
SELECT e FROM Experience e JOIN (SELECT f FROM Follow f WHERE f.username = :username AND f.contentType = :contentType) AS A ON (e.experienceId = A.contentId);
Its SQL equivalent that currently works is
SELECT t_experiences.* FROM t_experiences JOIN (SELECT * FROM t_follows WHERE t_follows.username = :username AND t_follows.content_type = :contentType) AS A ON (t_experiences.experience_id = A.content_id);
Where t_experiences.experience_id is equivalent to Experience.experienceId, etc. The current error in the HQL is on the first ( with unexpected token: ( error.
Any help would be greatly appreciated!
Why don.t you try this:
SELECT e.experienceId FROM Experience e, Follow f WHERE f.username = :username AND f.contentType = :contentType AND (e.experienceId = f.contentId);
I think this should work for you.
Note: Replace e.experienceId by parameters which you want.

Jooq query issue with case

I wrote this mysql query and tried to convert it to JOOQ query but not succeeded , this is mysql query
SELECT `P`.`phone_number`, `A`.`emp_no`,
SUM(CASE WHEN VCG.vid IN (
SELECT gv.vid FROM `grvas` gv JOIN gprs gr ON gr.id=gv.grid
WHERE gr.id=G.id AND gv.stdate < '2011-08-15' AND gv.enddate > '2011-09-14')
THEN VCG.amount END) AS allow,
... etc...
How can i convert this query to JOOQ query ?
Thanks,
This:
SUM(
CASE
WHEN VCG.vid IN (
SELECT gv.vid
FROM `grvas` gv
JOIN gprs gr ON gr.id=gv.grid
WHERE gr.id=G.id
AND gv.stdate < '2011-08-15'
AND gv.enddate > '2011-09-14'
)
THEN VCG.amount
END
) AS allow
Would translate to something like this:
import static org.jooq.impl.DSL.*;
// And then
sum(
decode()
.when(VCG.VID.in(
select(GRVAS.VID)
.from(GRVAS)
.join(GPRS).on(GPRS.ID.eq(GRVAS.GRID))
.where(GPRS.ID.eq(G.ID))
.and(GRVAS.STDATE.lt(Date.valueOf("2011-08-15")))
.and(GRVAS.ENDDATE.gt(Date.valueOf("2011-09-14")))
)), VCG.AMOUNT)
).as("allow")
The above example omitted table aliasing in the subquery of the IN predicate, to simplify things. Of course, you could go on and alias all those tables as well.
I couldn't find a proper way to convert above sql to JOOQ but i used
String sql="SELECT `P`.`phone_number`, `A`.`emp_no`,
SUM(CASE WHEN VCG.vid IN (
SELECT gv.vid FROM `grvas` gv JOIN gprs gr ON gr.id=gv.grid
WHERE gr.id=G.id AND gv.stdate < '2011-08-15' AND gv.enddate > '2011-09-14')
THEN VCG.amount END) AS allow,
... etc... " ;
Result<Record> res = f.fetch(sql);
This work fine
Thanks

Categories