Creating inner query in hibernate - java

how to add a set parameter() metheod inside the inner query in hibernate?
I have try to do like this but already have a errors
this is my code
Query query=session.createQuery("select eq.euipmentName,eq.type from Euipment eq where eq.id in(select euipment from Quotation qt where qt. supQuotation=:ids)");
query.setParameter("ids",id);
list = (List<Euipment>)query.list();

I've done some corrections about your query:
1. qt. supQuotation has a space, I've removed
2. euipment in you sub query haven't alias, I add qt
String hql =
"select eq.euipmentName,eq.type " +
" from Euipment eq " +
" where eq.id in (select qt.euipment from Quotation qt where qt.supQuotation = :ids)";
Query query = session.createQuery(hql);
query.setParameter("ids",id);
list = (List<Euipment>)query.list();
Tell me, if it's OK
If not OK, please post here the error, and check if you have put in hibernate mappping file your classes

From Hibernate Documentation:
Execution of native SQL queries is controlled via the SQLQuery
interface, which is obtained by calling Session.createSQLQuery().
createQuery() creates Query object using the HQL syntax.
createSQLQuery() creates Query object using the native SQL syntax.
So replace createQuery with createSQLQuery for native SQL query.

Try with Criteria
Criteria c = getSession().createCriteria(Euipment.class, "e");
c.createAlias("e.quotation", "q"); // inner join by default
c.add(Restrictions.eq("q.supQuotation", id));
list = (List<Euipment>)c.list();

Related

Criteria API limit results in subquery

I'm trying to write a query similar to
select * from Table a
where a.parent_id in
(select b.id from Table b
where b.state_cd = ?
and rownum < 100)
using the Criteria API. I can achieve the query without the rownum limitation on the subquery fine using similar code to https://stackoverflow.com/a/4668015/597419 but I cannot seem to figure out how to appose a limit on the Subquery
In Hibernate, you can add the actual SQL restriction, but it is worth noting this will be Oracle-specific. If you switched over to PostgreSQL, this would break and you'd need LIMIT 100 instead.
DetachedCriteria criteria = DetachedCriteria.forClass(Domain.class)
.add(Restrictions.sqlRestriction("rownum < 100"));
In the JPA API, the short answer is that you can't... In your question you proposed using the Criteria API (along with a SubQuery). However it is not until you actually call EntityManager.createQuery(criteriaQuery) that you'll get a TypedQuery where you can specify the maxResult value.
That said, you could break it into 2 queries, the first where you get the inner-select results (max 100) and then a 2nd Criteria where you take the resulting list in an in():
// inner query
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<YourClass> innerCriteriaQuery = cb.createQuery(YourClass.class);
Root<YourClass> yourClass = innerCriteriaQuery.from(YourClass.class);
innerCriteriaQuery.select(yourClass).where(
cb.equal(yourClass.get(YourClass_.stateCode), someStateValue));
// list of 100 parent ids
List<YourClass> list = em.createQuery(innerCriteriaQuery).setMaxResults(100).getResultList();
// outer query
CriteriaQuery<YourClass> criteriaQuery = cb.createQuery(YourClass.class);
Root<YourClass> yourClass = criteriaQuery.from(YourClass.class);
criteriaQuery.select(yourClass).where(
cb.in(yourClass.get(YourClass_.parentId)).value(list);
return em.createQuery(criteriaQuery).getResultList();
There is no JPA Criteria solution for this. You could make use of a custom SQL function that runs during SQL query generation time. All JPA providers support something like that in one way or another.
If you don't want to implement that yourself or even want a proper API for constructing such queries, I can only recommend you the library I implemented called Blaze-Persistence.
Here is the documentation showcasing the limit/offset use case with subqueries: https://persistence.blazebit.com/documentation/core/manual/en_US/index.html#pagination
Your query could look like this with the query builder API:
criteriaBuilderFactory.create(entityManager, SomeEntity.class)
.where("id").in()
.select("subEntity.id")
.from(SomeEntity.class, "subEntity")
.where("subEntity.state").eq(someValue)
.orderByAsc("subEntity.id")
.setMaxResults(100)
.end()
It essentially boils down to using the LIMIT SQL function that is registered by Blaze-Persistence. So when you bootstrap Blaze-Persistence with your EntityManagerFactory, you should even be able to use it like this
entityManager.createQuery(
"select * from SomeEntity where id IN(LIMIT((" +
" select id " +
" from SomeEntity subEntity " +
" where subEntity.state = :someParam " +
" order by subEntity.id asc" +
"),1)) "
)
or something like
criteriaQuery.where(
cb.in(yourClass.get(YourClass_.parentId)).value(cb.function("LIMIT", subquery));
If you are using EclipseLink the calling convention of such functions looks like OPERATOR('LIMIT', ...).

How can I correctly implement an Hibernate SQL query starting from an SQL query that count the number of rows?

I am absolutly new in Hibernate and I have the following problem.
I have this standard SQL query:
SELECT count(*)
FROM TID003_ANAGEDIFICIO anagraficaEdificio
INNER JOIN TID002_CANDIDATURA candidatura
ON (candidatura.PRG_PAR = anagraficaEdificio.PRG_PAR AND candidatura.PRG_CAN = anagraficaEdificio.PRG_CAN)
INNER JOIN TID001_ANAGPARTECIPA anagPartecipa ON(anagPartecipa.PRG_PAR = candidatura.PRG_PAR)
INNER JOIN anagrafiche.TPG1029_PROVNUOIST provNuovIst ON (provNuovIst.COD_PRV_NIS = anagPartecipa.COD_PRV_NIS)
WHERE anagraficaEdificio.FLG_GRA = 1 AND provNuovIst.COD_REG = "SI";
This works fine and return an integer number.
The important thing to know is that in this query the only
parameter that can change (inserted by the user in the frontend of a webappplication) is the last one (this one: provNuovIst.COD_REG = "SI").
So, the application on which I am working use Hibernate and the requirement say that I have to implement this query using Hibernate Native SQL, I have found this tutorial:
http://www.tutorialspoint.com/hibernate/hibernate_native_sql.htm
that show this example:
String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
query.setParameter("employee_id", 10);
List results = query.list();
that, from what I have understand (correct me if I am doing wrong assertion), involves the use of an Employee model class. So th prvious query first define the query (using the :param_name syntax for the parameter), then create an SQLQuery Hibernate object, add the class used for the result, set the previous parameter neam and finally obtain a List (that I think Hibernate create as something like an ArrayList) with the retrieved object.
My problem is that I simply I have to obtain an integer value (because I have a SELECT count(*), so I will obtain an integer value and not a set of rows).
So how can I correctly use the Hibernate Native SQL to implement my SQL query into my Hibernate repository class?
Use SQLQuery.uniqueResult to retrieve a single value from the query:
String sql = "SELECT count(*) ...";
SQLQuery query = session.createSQLQuery(sql);
// set parameters...
int count = ((Number)query.uniqueResult()).intValue();

Hibernate generates error SQL like ".=."

I have 3 tables in Oracle DB which relationship is #ManyToMany. So I have 2 significant tables and one for mappings.
I create a classes with name (if you want I can show my classes) named Entities, Keywords (I understand that naming is not correct but this is not my project I only do optimizations).
I use hibernate version 4.3.4.
I write query like this:
session = HibernateUtil.getSessionFactory().openSession();
String sql = "SELECT DISTINCT r FROM Rules r, Entities e " +
" WHERE r.entities = e.rules " +
" AND e IN :entities ";
Query query = session.createQuery(sql);
query.setParameterList("entities", entitiesList);
List<Rules> rulesList = query.list();
BUT! Hibernate generate strange SQL
Hibernate:
select
rules0_.rule_id as rule_id1_11_,
rules0_.rule as rule2_11_
from
rules rules0_,
entities entities1_,
rules_entities entities2_,
entities entities3_,
rules_entities rules4_,
rules rules5_
where
rules0_.rule_id=entities2_.rule_id
and entities2_.entity_id=entities3_.entity_id
and entities1_.entity_id=rules4_.entity_id
and rules4_.rule_id=rules5_.rule_id
and .=.
and (
entities1_.entity_id in (
? , ? , ? , ?
)
)
When I try to execute this query I receive that error:
java.sql.SQLException: ORA-00936: missing expression
When I copy this query to OracleDevepoler he didn`t like this expression "and .=.". Without that query executes correct.
What am I doing wrong ?
Maybe you used bad join in your query? From context i conclude that you should use something like that:
"SELECT DISTINCT r FROM Rules r inner join r.entities e " +
" WHERE e IN :entities ";
I think the correct query could be
select distinct e.rules from Entities where e.entityId in :entities
This is if Keywords is your join table and you have a collection of rules in Entities
If it isn't, can you show the mappings please, it could help.

HQL not return results but when queried directly it works

I am trying below query in HQL but I get no results. Can someone help me on why I don't get any results? I tried to query the DB directly (please see SQL below) and i get 12 records. But HQL gives me 0 records.
"cause" I input the following String - "'XXX1','YYY 2'"
DB I use is Pracle 11g.
String queryStr = "from DefectsTran t join t.defects d where d.releaseName=:rel and t.defectCause in :cause and t.latestRecord=:lastrec";
Query q = session.createQuery(queryStr);
q.setString("rel", release);
q.setString("cause", filter2);
q.setString("lastrec", "Y");
SQL query that works fine when I use in TOAD.
select count(*)
from QC10.defects_tran t
inner join QC10.defects on DEFECT_ID_FK_DT = RECORD_ID
where
DEFECT_CAUSE in ('Data Request Issue', 'Functioning as Expected', 'User Education Required', 'Test Script Incorrect', 'Test Specific')
and t.latest_record = 'Y'
Instead of q.setString("cause", filter2); use q.setParameterList("cause", filter2);. filter2 has to be of a Collection subtype. Please read more about other overloading available for setParameterList: http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html

jpa select statement with subnets

I am trying to write query with multiple select subnets in it.But I defined a nativequery
I am giving error. Compiler specifies that "(" after "from" is not proper. How can I define
a native query in JPA 2.0
For eaxmple:
SELECT *
from (SELECT ****C) REI3 where column1 != 1
GROUP BY REI3.column2 order by REI3.column3 ASC
JPA does not have too much to do with validating SQL syntax, query is passed to JDBC driver. Likely you are trying run query such a way, that it is interpreted as JP QL. Instead try following method to execute it as
Query q = em.createNativeQuery("Your SQL here");
Other alternative is to use NamedNativeQuery Example

Categories

Resources