How to effectively write named queries JPA - java

I have named queries which looks like the following:
#NamedQueries({
#NamedQuery(name = "table.getvalues", query = "select p from table p where p.a = :a and p.b = :b and p.c = :c order by id"),
#NamedQuery(name = "table.getvalueswhencisnull", query = "select p from table p where p.a = :a and p.b = :b and p.c is null order by id")
})
The only difference between 2 named queries is the the value of the c,c can be null and the syntax of the sql query differs only because of that.
Is there a way where I can club both the statements effectively?

use this :
select p from table p where p.a = :a and p.b = :b and (p.c is null or p.c=:c) order by id

Maybe this filter does a conditional selection.
...AND (p.c=:c OR (:c IS NULL and p.c IS NULL))...

Related

Case Insensitive search in hibernate

I want to perform a hibernate named query but its giving hibernate syntax exception. In SQL it's running properly..chart will come as a query parameter and query value = 'chart'?
SELECT * FROM faq WHERE UPPER(answer) LIKE UPPER('%chart%')
select f from Faq f where lower(f.question) like lower('%:query%') or lower(f.answer) like lower('%:query%')
#NamedQuery(name = "findQuesAnsByQuery", query = "select f from Faq f where lower(f.question) like lower('%:query%') or lower(f.answer) like lower('%:query%')")
Trace:
[0] = {java.lang.StackTraceElement#16677}"org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:679)"
[1] = {java.lang.StackTraceElement#16678}"org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)"
[2] = {java.lang.StackTraceElement#16679}"org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)"
[3] = {java.lang.StackTraceElement#16680}"org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)"
[4] = {java.lang.StackTraceElement#16681}"org.springframework.orm.hibernate3.HibernateTemplate.findByNamedQuery(HibernateTemplate.java:979)"
[5] = {java.lang.StackTraceElement#16682}"org.springframework.orm.hibernate3.HibernateTemplate.findByNamedQuery(HibernateTemplate.java:971)"
[6] = {java.lang.StackTraceElement#16683}"com.hk.impl.dao.BaseDaoImpl.findByNamedQuery(BaseDaoImpl.java:157)"
I think your problem is in using the '%:query%'.. in the query.. Change to this:
#NamedQuery(name = "findQuesAnsByQuery"
, query = "select f from Faq f
where lower(f.question) like lower(CONCAT('%', :query, '%'))
or lower(f.answer) like lower(CONCAT('%', :query, '%'))")
or
#NamedQuery(name = "findQuesAnsByQuery"
, query = "select f from Faq f
where lower(f.question) like lower(:query)
or lower(f.answer) like lower(:query)")
and then set the param:
.setString("query", "%" + query+ "%")

named query to fetch result by using IN clause with null or without null conditionally

I need a single named query that fulfills below both named query conditions only by setting the Query parameter.
Named Query, to fetch record where "softwareVersion" is null OR softwareVersion matched with the list.
#NamedQuery(name = "getIPDetectionDetailsForPanIndia",
query = "select cssc.css.sapId,
cssc.css.hostName,
cssc.cssGoldenConfiguration.category,
cssc.cssGoldenConfiguration.parameter,
cssc.cssGoldenConfiguration.vendor,
cssc.recommendedValue,
cssc.actualValue,
cssc.cssGoldenConfiguration.id,
cssc.cssGoldenConfiguration.information,
cssc.css.softwareVersion,
jioc.name,
cssc.cssGoldenConfiguration.impact,
cssc.cssGoldenConfiguration.command
from CssComplianceDetail cssc
join cssc.css c
left join c.cluster club
left join clus.jiocenter jioc
where cssc.cssGoldenConfiguration.impact in (:impactType)
and cssc.cssGoldenConfiguration.category in (:category)
and TO_CHAR(cssc.creationDate, 'yyyy-MM-dd') = TO_CHAR(:date, 'yyyy-MM-dd')
and (cssc.css.softwareVersion in (:softwareVersion)
or cssc.css.softwareVersion is null)";
Named Query, to fatch record where "softwareVersion" matched with the list only, no need to fatch null softwareVersion.
#NamedQuery(name = "getIPDetectionDetailsForPanIndiaAcceptNull",
query = "select cssc.css.sapId,
cssc.css.hostName,
cssc.cssGoldenConfiguration.category,
cssc.cssGoldenConfiguration.parameter,
cssc.cssGoldenConfiguration.vendor,
cssc.recommendedValue,
cssc.actualValue,
cssc.cssGoldenConfiguration.id,
cssc.cssGoldenConfiguration.information,
cssc.css.softwareVersion,
jioc.name,
cssc.cssGoldenConfiguration.impact,
cssc.cssGoldenConfiguration.command
from CssComplianceDetail cssc
join cssc.css c
left join c.cluster club
left join clus.jiocenter join
where cssc.cssGoldenConfiguration.impact in (:impactType)
and cssc.cssGoldenConfiguration.category in (:category)
and TO_CHAR(cssc.creationDate, 'yyyy-MM-dd') = TO_CHAR(:date, 'yyyy-MM-dd')
and cssc.css.softwareVersion in (:softwareVersion)";
Below is my Java code:
List softwareVersion = new ArrayList();
if(softwareVersion.contains("All")) {
query = getEntityManager().createNamedQuery("getIPDetectionCountForPanIndiaAcceptNull");
} else {
query = getEntityManager().createNamedQuery("getIPDetectionCountForPanIndia");
}
query.setParameter("softwareVersion", softwareVersion);

JPA 2 + Criteria API

Employee (table)
id - int
ctd_id - int
message - char
SELECT a.*
FROM Employee a left outer join
( select * from Employee where message = 23 ) b
on a.ctd_id = b.ctd_id
where a.message = 22 and b.id is null;
This is what i tried
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> criteria = cb.createQuery(Employee.class);
Root<Employee> emp = criteria.from(Employee.class);
CriteriaQuery<Employee> sq = c.select(emp);
Subquery<Employee> sq2 = criteria.subquery(Employee.class);
Root<Employee> emp2 = sq2.from(Employee.class);
Join<Employee,Employee> sqEmp = emp2.join("ctd_id", JoinType.LEFT);
sq.select(sqemp).where(cb.equal(emp2.get("message"), cb.parameter(String.class, "23")));
sq.where(cb.in(path).value(sq2));
TypedQuery<Employee> q = em.createQuery(criteria);
List<Employee> employeess = q.getResultList()
But, i am not able to understand as to how i should apply a join on a subquery with where clause.
please help .
JPA does not support sub-queries in the FROM clause.
Either use SQL for your query, or rewrite it not to have a sub-query in the from clause, it doesn't look like you need it.

Subquery in where clause with CriteriaQuery

Can anybody give me some hints on how to put that kind of subquery in a CriteriaQuery? (I'm using JPA 2.0 - Hibernate 4.x)
SELECT a, b, c FROM tableA WHERE a = (SELECT d FROM tableB WHERE tableB.id = 3) - the second select will always get a single result or null.
Try something like the following example to create a subquery:
CriteriaQuery<Object[]> cq = cb.createQuery(Object[].class);
Root tableA = cq.from(TableA.class);
Subquery<String> sq = cq.subquery(TableB.class);
Root tableB = cq.from(TableB.class);
sq.select(tableB.get("d"));
sq.where(cb.equal(tableB.get("id"), 3));
cq.multiselect(
cb.get("a"),
cb.get("b"),
cb.get("c"));
cq.where(cb.equal(tableA.get("a"), sq));
List<Object[]> = em.createQuery(cq).getResultList();
Note the code has not been tested due to the lack of an IDE nearby.
You can use DetachedCriteria to represend the sub-query. Your code should look something like:
DetachedCriteria subCriteria = DetachedCriteria.forClass(TableB.class);
subCriteria.add(Property.forName("id").eq(3)); //WHERE tableB.id = 3
subCriteria.setProjection(Projections.property("d")); // SELECT d from
DetachedCriteria criteria = DetachedCriteria.forClass(getPersistentClass());
criteria.add(Property.forName("a").eq(subCriteria)); //a = (sub-query)
criteria.setProjection(Projections.property("a"); //SELECT a
criteria.setProjection(Projections.property("b"); //SELECT b
criteria.setProjection(Projections.property("c"); //SELECT c
return getHibernateTemplate().findByCriteria(criteria);

complex query to equivalent criteriabuilder query(EntityManager)

My Query is this:
query1 = select a.id from entity1 a where a.id in (:List1)
and not exists (select ex2 from entity2 ex2 where ex2.assignedId = a.id)
union
select ex.assignedId from entity2 ex ,entity3 pi
where ex.entity3Id = pi.id and ex.assignedId in (:List1)
and ex.assignedTypeId = :assignedTypeId and pi.processStatus = :status
and not exists
(select ex1.assignedId from entity2 ex1 , entity3 pi1
where ex1.entity3Id = pi1.id and ex1.assignedId = ex.assignedId
and ex1.assignedTypeId = :assignedTypeId
and pi1.processStatus <> :status);
and while trying to execute query,
Query existingIds=em.createQuery(query1); //With all parameters set
throws NullPointerException in line 87 of org.hibernate.hql.ast.ParameterTranslationsImpl
completely checked all the braces and parameters. The equivalent conversion works in mysql.
Can someone assist me in converting the query with CriteriaBuilder, finding it difficult to make the conversion.
Not sure if JPQL supports union operation at all. Are you putting this as NamedQuery or you are creating on the fly (entityManager.createQuery()) ?

Categories

Resources