HQL transformation - java

I am a newbie with HQL and I am trying to do this :
select count(T) from (
select inscription, max(wrd_step) as max
from table aa
where rd_context = ?
group by inscription
) as T
where T.max = ?
The error is :
Caused by: org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ( near line 1, column 21 [select count(T) from( select inscription, max(wrd_step) from table aa where rd_context = ? group by inscription) as T where T.max = ?]
Thanks
EDIT :
The query in HQL is :
SELECT count(distinct inscription)
FROM Entity
WHERE inscription in (
select distinct inscription
from Entity
where rd_context = ?
group by inscription
having max(wrd_step) = ?
)

Hibernate documentation states:
Note that HQL subqueries can occur only in the select or where clauses.
http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#queryhql-subqueries
But assuming table is a mapped entity (is it?), you can do this (not tested):
select count(aa)
from table aa
where rd_context = :param1
group by inscription
having max(wrd_step) = :param2

Related

Incorrect Syntax near WHERE error in generated SQL

I am generating the below SQL. From my code I am using a where condition list to collect all the Where logic and insert it after the Join logic is set-up. However, I am getting a very generic syntax error and I can't figure out why. I am pretty sure the logic is properly organized however, when inserting the where statement it throws the syntax error
Incorrect Syntax near WHERE
The {h-schema} are just generated database and table names.
The code:
SELECT count(*) AS ID
FROM (
SELECT 'PREAPPROVAL' AS type, pa.id AS id FROM {h-schema}preapproval AS pa
LEFT JOIN {h-schema}risk_limit AS lim ON pa.limit_id = lim.id
LEFT JOIN {h-schema}desk AS d ON lim.desk_enterprise_id = d.enterprise_id AND CAST(pa.creation_date_time AS date) BETWEEN d.start_date AND d.end_date
WHERE pa.status = 'APPROVED' AND pd.end_date = NULL <-------------------------SYNTAX ERR HERE
OR pa.status = 'DECLINED' AND pa.completion_date_time > '2021-01-28 13:02:13'
OR pa.status = 'IN_PROGRESS'
OR pa.creation_date_time > '2021-01-28 13:02:13'
AND COALESCE(lim.policy_enterprise_id, d.policy_enterprise_id) IN (6)
UNION
SELECT 'BREACH' AS type, br.id AS id FROM {h-schema}breach AS br
LEFT JOIN {h-schema}risk_limit AS lim ON br.limit_id = lim.id
LEFT JOIN {h-schema}desk AS d ON lim.desk_enterprise_id = d.enterprise_id
AND br.reporting_date BETWEEN d.start_date AND d.end_date
LEFT JOIN {h-schema}valid_breach_recommendation AS vbr_approve ON vbr_approve.id = (SELECT TOP(1) id FROM {h-schema}valid_breach_recommendation
WHERE breach_id = br.id AND outcome = 'APPROVE'
ORDER BY creation_date_time DESC, id DESC)
LEFT JOIN {h-schema}valid_breach_decision AS vbd
ON vbd.id = (SELECT TOP(1) id FROM {h-schema}valid_breach_decision
WHERE breach_id = br.id
ORDER BY creation_date_time DESC, id DESC)
LEFT JOIN {h-schema}breach AS child_br ON br.id = child_br.parent_breach_id
WHERE br.status = 'APPROVED' AND vbd.end_date = NULL <--------------------SYNTAX ERR HERE
OR br.status = 'DECLINED' AND br.completion_date_time > '2021-01-28 13:02:14'
OR br.status = 'IN_PROGRESS'
OR br.creation_date_time > '2021-01-28 13:02:14'
AND child_br.id IS NULL
AND CASE br.status
WHEN 'IN_PROGRESS' THEN vbr_approve.start_date
WHEN 'APPROVED' THEN vbd.start_date
WHEN 'CANCELLED' THEN vbd.start_date
ELSE NULL
END IS NOT NULL AND COALESCE(lim.policy_enterprise_id, d.policy_enterprise_id) IN (6)
) AS issue
This is actually version issue. In latest version of SQL support like
create procedure sp_name
(
#name varchar(50) NULL
)
...
But the older version of SQL doesn't support with this way. For older version we need to provide '=NULL'
There is some syntax error due to {h-schema}, remove {h-schema} and your code has no syntax error. Remove {h-schema} and your code works fine.

Subquery with Inner Join in HQL

I want to print title from Movies table which has Foreign key Movie_id in Rating table.In rating table we have to get top 10 results based on movie_id occurrence .Since Limit is not allowed in HQL so setMaxResults is used
Query q=session.createQuery("select Title from Movies as M Inner Join ( SELECT Movie_id, COUNT(*) FROM Rating GROUP BY Movie_id ORDER BY COUNT(*) DESC LIMIT 10 ) as R ON M.Movie_id=R.Movie_id").setMaxResults(10);
Exception is:
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 59 [select Title from com.rahul.model.Movies as M Inner Join ( SELECT Movie_id, COUNT(*) FROM com.rahul.model.Rating GROUP BY Movie_id ORDER BY COUNT(*) DESC LIMIT 10 ) as R ON M.Movie_id=R.Movie_id]
Since HQL doesn't support subquery how to achieve it ?
You can write this query as a JOIN/GROUP BY:
select m.Title
from Movies m Inner Join
Rating r
on m.Movie_id = r.Movie_id
group by m.Movie_Id, m.Title
order by count(*) desc
limit 10;
Resolved
Query q=session.createQuery("select m.title from Movies m Inner Join Rating r on m.movie_id = r.movie_id group by m.movie_id, m.title order by count(*) desc").setMaxResults(10);

Data is not ordered correctly with pagination: Sql server and Hibernate 3.6.10

EDIT: the problem is related to the presence of subqueries in the select part of the translated query. This seems to mess with the numbering given by
the pagination.
We recently changed dialect from SqlServerDialect to SqlServer2008Dialect in out hibernate configuration and hibernate it's starting to translate the queries that are paginated with this sql server query:
WITH query AS (select ROW_NUMBER() OVER (order by this_.numero asc) as __hibernate_row_nr__,
this_.id as id834_0_, this_.numero as numero834_0_, this_.ragione_sociale as ragione9_834_0_, this_.anagrafica_fiscale as anagrafica10_834_0_,
this_.partita_iva as partita11_834_0_, this_.codice_fiscale as codice12_834_0_, this_.note as note834_0_, this_.data_prospect_dal as data14_834_0_,
this_.dt_inserimento as dt15_834_0_, this_.dt_modifica as dt16_834_0_, this_.nome as nome834_0_, this_.cognome as cognome834_0_,
this_.dt_nascita as dt19_834_0_, this_.fl_piva_duplicata as fl20_834_0_, this_.mail_cliente as mail21_834_0_, this_.fl_capogruppo as fl22_834_0_,
this_.fk_e2_crm_prospects as fk26_834_0_, this_.fl_duplicato as fl23_834_0_, this_.fl_a_consumo as fl4_834_0_,
this_.codice_importazione as codice24_834_0_, this_.codice_attivita as codice38_834_0_, this_.fk_e0_utente_inserimento as fk5_834_0_,
this_.fk_e0_utente_modifica as fk6_834_0_, this_.fk_e0_prof_nodo as fk7_834_0_, this_.fk_e0_decod_classe_dim_pr as fk27_834_0_,
this_.fk_e0_decod_tipo_prospect as fk28_834_0_, this_.fk_e0_decod_codice_ateco as fk29_834_0_, this_.fk_comune_di_nascita as fk30_834_0_,
this_.fk_e0_decod_gp_ind_com as fk31_834_0_, this_.fk_e0_decod_seg_com as fk32_834_0_, this_.fk_e0_decod_sotto_seg_com as fk33_834_0_,
this_.fk_e0_natura_cliente as fk34_834_0_, this_.fk_e0_nazione_nascita as fk36_834_0_, this_.fk_e0_decod_prov_pros as fk35_834_0_,
this_.fk_e2_com_punto_stradario as fk37_834_0_, replace(replace(replace(this_.ragione_sociale,'.',''),'-',''),' ','') as formula1662_0_,
( select u.user_logged from users u join e2_crm_dett_prospects p on u.id = p.fk_e0_decod_gestore_prospect
where p.fk_e2_crm_prospect = this_.id and p.fk_e0_prof_nodo = this_.fk_e0_prof_nodo) as formula1663_0_,
( select s.descrizione from e0_decod_tipi_stato_prospect s join e2_crm_dett_prospects p on s.id = p.fk_e0_decod_stato_prospect
where p.fk_e2_crm_prospect = this_.id and p.fk_e0_prof_nodo = this_.fk_e0_prof_nodo) as formula1664_0_,
( select i.num_dipendenti from e2_crm_info_camerali_prosp i where i.fk_e2_crm_prospect = this_.id
and i.dt_inserimento = ( select max(p.dt_inserimento)
from e2_crm_info_camerali_prosp p
where p.fk_e2_crm_prospect = this_.id ) ) as formula1665_0_
from e2_crm_prospects this_ where this_.fl_duplicato=? )
SELECT * FROM query WHERE __hibernate_row_nr__ BETWEEN ? AND ?
The problem is that the resulting data is not ordered by the numero column.
Using the old dialect the paginated query was translated with a TOP clause with an ORDER BY numero at the end of the query and the rows where ordered correctly.
The query is build using criteria and ordered and paginated like this:
Criteria criteria = session.createCriteria(ProspectRicerca.class,"padre");
criteria.add(Restrictions.eq(Constant.PROSPECT_FLAG_DUPLICATO, false));
criteria.addOrder(Order.asc("numero"));
criteria.setFirstResult(pageNumber*numElementForPage);
criteria.setMaxResults(numElementForPage);
lista = criteria.list();
The hibernate version is 3.6.10 and we use Sql Server 2008
This is the result of the query executed in sql server, as you can see the rows are not ordered (the __hibernate_row_nr__ column is coherent with the numero column order.

How can I JOIN multiple table columns in jpa and jpql

I'm new with JPA and JPQL. I'm trying to query a database grab rows from a table that contains mostly index's of the names contained in other tables.
This is the query in mysql that I'm trying to recreate:
SELECT COUNT(*) as PieceCount,
shifttimes.shiftid as ShiftId,
specienames.NameText as SpecieName,
gradenames.NameText as Grade,
DryerNum,
CreatedLocal
from sheets, shifttimes, specienames, gradenames
WHERE sheets.ShiftIndex = shifttimes.ShiftIndex AND
sheets.SpecieNameIndex = specienames.NameIndex AND
sheets.gradenameindex = gradenames.NameIndex AND
CreatedLocal >= '" . $begin . $StartGraveyard
' AND CreatedLocal < '" . $end . $StartGraveyard
GROUP BY ShiftId, SpecieName, Grade, DryerNum;
This is the query I have and as far as I've gotten:
SELECT COUNT(s.createdLocal),
g.nameText gName,
p.nameText pName
FROM Sheets s , GradeNames g , SpecieNames p
JOIN s.gradeNameIndex gIndex ,
JOIN s.specieNameIndex pIndex
WHERE gIndex = g.nameIndex AND
pIndex = p.nameIndex
GROUP BY gName , pName
This is the Java Glassfish error that I am receiving:
java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Syntax error parsing [SELECT COUNT(s.createdLocal), g.nameText, p.nameText FROM Sheets s , GradeNames g , SpecieNames p JOIN s.gradeNameIndex gIndex , JOIN s.specieNameIndex pIndex WHERE gIndex = g.nameIndex AND pIndex = p.nameIndex GROUP BY g.nameText , p.nameText].
[128, 128] The range variable declaration must be specified.
First off all, sorry, but this is not an answer but BIG comment...
You should better stop using this syntax FROM Sheets s , GradeNames g , SpecieNames p.
All tables you need should be properly JOINed by ON clause.
Any JOIN statement should have ON clause and should not have , any comma at the end.
If I understood your 2nd query correctly it must be something like:
SELECT COUNT(s.createdLocal),
g.nameText gName,
p.nameText pName
FROM Sheets s
JOIN GradeNames g
ON s.gradeNameIndex = g.nameIndex
JOIN SpecieNames p
ON s.specieNameIndex = p.nameIndex
GROUP BY gName , pName

Hibernate DetachedCriteria Query with and clause in subselect

How can I solve this query with Hibernate's detached criteria? The hardest part for me is to bring the and u1.abrechnungsDatum is null into the subselect.
I want a query like this:
select *
from
patient as p
where
p.krankenstand = ?
and
? < ( select count(*) from ueberweisung u1 where p.id = u1.patient_id
and u1.abrechnungsDatum is null)
I have tried it with this
DetachedCriteria dc = DetachedCriteria.forClass(Patient.class, "patient");
dc.add(Restrictions.eq("krankenstand", true));
DetachedCriteria nab = dc.createCriteria("ueberweisungs", "nab");
nab.add(Restrictions.isNull("nab.abrechnungsDatum"));
dc.add(Restrictions.sizeGt("ueberweisungs", 0));
which gives me the following SQL-Statement
select
*
from
patient this_
inner join
ueberweisung nab1_
on this_.id=nab1_.patient_id
where
this_.krankenstand=?
and nab1_.abrechnungsDatum is null
and ? < (
select
count(*)
from
ueberweisung
where
this_.id=patient_id
)
As you can see, the and-clause for the field abrechnungsDatum is not inside the subselect. How can I achieve to get this inside?
Try this instead:
DetachedCriteria dc = DetachedCriteria.forClass(Patient.class, "patient");
dc.add(Restrictions.eq("krankenstand", true));
DetachedCriteria subquery = DetachedCriteria.forClass(Ueberweisung.class);
subquery.add(Restrictions.isNull("abrechnungsDatum"));
dc.add(Subqueries.ltAll(0, subquery));

Categories