count hibernate and Named Query - java

I want to count elements from table using NamedQueries.
NamedQuery is:
#NamedQuery(name = Advertisement.countBySubcategoryList, query = "select count(*) from Advertisement where subcategoryId IN (:subcategoryId)")
and:
public static final String countBySubcategoryList = "Advertisement.countBySubcategoryList";
In model I use:
List<Advertisement> advertisements = session.getNamedQuery(Advertisement.countBySubcategoryList)
.setParameterList("subcategoryId", subcategoryIds)
.list();
How to get count value from query?

Your query should be something like
select count(a) from Advertisement a where a.subcategoryId IN (:subcategoryId)
And you should call it like this
Long count = (Long)session.getNamedQuery(Advertisement.countBySubcategoryList)
.setParameterList("subcategoryId", subcategoryIds)
.uniqueResult();
EDIT
Hibernate versions prior to 4 returned Integer instead of Long for this type of query.

You can even try this, if you are hibernate version < 4
int count =
((Number)em.createNamedQuery("Advertisement.countBySubcategoryList").getSingleResult()).intValue();
if you are hibernate version >= 4 . #Maric is right
Long count =
(Long)session.getNamedQuery(Advertisement.countBySubcategoryList)
.setParameterList("subcategoryId", subcategoryIds)
.uniqueResult();

Related

Select Top 1 records from MS SQL using Spring Data JPA

I am using the below #Query annotation to get the first few record from MS-SQL. It's showing error saying "< operator > or AS expected..."
#Query("SELECT Top 1 * FROM NEVS010_VEH_ACTV_COMMAND C WHERE C.EVS014_VIN = :vin ORDER BY C.EVS010_CREATE_S DESC")
CommandStatus findCommandStatusByVinOrderByCreatedTimestampDesc(#Param("vin") String vin);
You can also use findFirst and findTop as mentioned in the Docs:
findFirstByVinOrderByCreatedTimestampDesc(String vin)
Since the query is SQL (and not JPQL) one needs to set nativeQuery = true in the annotation:
#Query(nativeQuery = true, value = "SELECT Top 1 * FROM NEVS010_VEH_ACTV_COMMAND C WHERE C.EVS014_VIN = :vin ORDER BY C.EVS010_CREATE_S DESC")
CommandStatus findCommandStatusByVinOrderByCreatedTimestampDesc(#Param("vin") String vin);
For custom Queries without using nativeQuery, the field ROWNUM can be used.
Ex (in Kotlin but the same idea works in Java):
#Query("""
SELECT a
FROM Account a
WHERE a.bla = :ble
AND ROWNUM = 1
ORDER BY a.modifiedDate DESC
""")
fun findWhatever(#Param("ble") someParam: String)
I haven't found that on any doc so far. I just tested and it worked for Oracle, MySQL and H2

EclipseLink Criteria API count in results after joining table

After ours of searching I was still unable to find a way to write this SQL equivalent in EclipseLink criteria query:
SELECT preke.*, count(nuotrauka.prid) AS cnt FROM preke LEFT JOIN nuotrauka ON nuotrauka.prid=preke.prid WHERE trash = 1 GROUP BY preke.prid ORDER BY cnt DESC
I tried joins, multiselects and etc. I need getResultList() to return me List within List like list[0] - (Preke)preke1, list[1] - (Integer)count1; list[0] - (Preke)preke2, list[1] - (Integer)count2 ... .
EDIT 1:
CriteriaBuilder cb = EntityManager.getInstance().getCriteriaBuilder();
CriteriaQuery criteriaQuery = cb.createQuery(Tuple.class);
Root<Preke> from = criteriaQuery.from(Preke.class);
Expression<Long> count = cb.count(from.get("images"));
criteriaQuery.where(cb.equal(from.get("trash"), true));
criteriaQuery.multiselect(from.alias("preke"), count.alias("count"));
criteriaQuery.groupBy(from.get("prid"));
TypedQuery<Tuple> typedQuery = EntityManager.getInstance().createQuery(criteriaQuery);
typedQuery.setFirstResult(PAGE * ITEMS_PER_PAGE);
typedQuery.setMaxResults(ITEMS_PER_PAGE);
prekes = typedQuery.getResultList();
...
for(Tuple t : prekes) {
Preke p = (Preke)t.get("preke");
long count = (long)t.get("count");
...
}
It give me following JPQL statement:
SELECT t0.prid AS a1,
...,
COUNT(t1.id)
FROM preke t0,
nuotrauka t1
WHERE
((t0.trash = ?) AND (t1.prid = t0.prid))
GROUP BY t0.prid LIMIT ?, ?
This is almost fine, but it doesn't include results where count is 0.
As above JPQL statement says - t1.prid = t0.prid should be the bad part, how to replace it? I think what I need here is a LEFT JOIN. But how to do it?
Instead of using
Expression<Long> count = cb.count(from.get("images"));
try using
Join<Preke, Nuotrauka> images = from.join("images", JoinType.LEFT);
Expression<Long> count = cb.count(images);

hibernate java select queries

i am new to this and today i tried to play hibernate with a method that returns the result of selected row...if is selected then it can return the result in int.. here is my method
public int validateSub(String slave, String source, String table){
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Query q = session.createQuery("from Subscribers where slave = :slave AND source = :source AND tbl = :tbl");
q.setParameter("slave", slave);
q.setParameter("source", source);
q.setParameter("tbl", table);
int result = q.executeUpdate();
return result;
}
from this method i tried to validate the 3 values that i get from the Subscribers table but at the end i tried to compile having this error
Exception in thread "Thread-0" org.hibernate.hql.QueryExecutionRequestException: Not supported for select queries [from com.datadistributor.main.Subscribers where slave = :slave AND source = :source AND tbl = :tbl]
You can have a look at the below links that how executeUpdate works, one is from the hibernate docs and other the java docs for JPA which defines when the exception is thrown by the method
http://docs.oracle.com/javaee/6/api/javax/persistence/Query.html#executeUpdate()
https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html#executeUpdate()
Alternatively you can use
List list = query.list();
int count = list != null ? list.size() : 0;
return count;
you are running a select query, Eventhough you are not using the select keyword here hibernate will add that as part of the generated SQL.
what you need to do to avoid the exception is the say
q.list();
now, this will return a List (here is the documentation).
if you are trying to get the size of the elements you can say
Query q = session.createQuery("select count(s) from Subscribers s where slave = :slave AND source = :source AND tbl = :tbl");
Long countOfRecords = (Long)q.list().get(0);
you can execute update statements as well in HQL, it follows a similar structure as SQL (except with object and properties).
Hope this helps.
here you want to select record so it is posible without select key word
sessionFactory sesionfatory;
ArrayList list = (ArrayList)sessionfactory.getCurruntSession().find(from table where name LIKE "xyz");
long size = list.get(0);
I also happened to make the same mistake today.
Your SQL statement is not correct.
You can try:
DELETE from Subscribers WHERE slave = :slave AND source
Try this:
int result = q.list().size();

How to implement sum of a field query in Hibernate?

How can we implement the Hibernate sqlprojection in my query?
Here is my query
SELECT sum(total_amount) as total,created_at from order where created_at < DATE_SUB(curdate(), INTERVAL 7 DAY) and doctor_id = 193 GROUP BY created_at
I have implement DATE_SUB function using sqlRestriction like this:
String sqlWhere = "created_at > DATE_SUB(curdate(), INTERVAL "+activityGraph+" DAY) AND doctor_id = "+id +" GROUP BY created_at";
Criteria criteria = Hibernatesession.createCriteria(Order.class);
criteria.add(Restrictions.sqlRestriction(sqlWhere));
But I don't know how I get the sum of a field using Hibernate query.
I found out that setProjection in Hibernate is used to get the sum as we desired but I don't know how to use it. Also here I want to use sqlRestriction to write WHERE condition for date_sub function.
So I will use setProjection and sqlRestriction in a single query.
You're making you life difficult. Why don't you simply compute the date limit in Java before executing the query?
Date today = DateUtils.truncate(new Date(), Calendar.DATE);
Date limit = DateUtils.addDays(today, -7);
And since the query is completely static, why using the Criteria API. HQL is much easier:
String hql = "SELECT sum(o.totalAmount) as total, o.createdAt from Order o"
+ " where o.createdAt < :limit"
+ " and o.doctor.id = 193"
+ " group by o.createdAt";
criteria.setProjection((Projections.sum("/* name of the mapping variable for total_amount*/")));
public int getSum() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Criteria criteria = session.createCriteria(Product.class);
criteria.setProjection(Projections.sum("productCount"));
List list = criteria.list();
session.getTransaction().commit();
return (int) list.get(0);
}
//hibernate mpping
<property name="productCount" type="int" column="PRODUCT_COUNT"/>

problem with HQL update

When I try to execute the following HQL query:
Query query = getSession().createQuery("update XYZ set status = 10");
query.executeUpdate();
I get this exception:
Exception in thread "main" org.hibernate.QueryException: query must begin with SELECT or FROM: update
EDIT:
I also tried following .But it doennot work either.
org.hibernate.Query query = getSession().createQuery("update XYZ t set t.status = 10");
EDIT2:
Making changes in hinbernate.cfg.xml solved my problem
Earlier i was using
setting hibernate.query.factory_class" = org.hibernate.hql.classic.ClassicQueryTranslatorFactor
Now am using following property
<property name="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>
Thats not an HQL query.
You want to import javax.persistence.Query which allows normal sql,
not org.hibernate.Query which works on entity objects.
If you want to use simple sql, you could also use PreparedStatement
However, if you really want to use hibernate, without taking advantage of entityobjects (totally defeating the point of using hibernate in the first place, imho) you could do it like this (reference docs):
String myUpdate = "update XYZ myAlias set myAlias.status = :newStatus";
// or String noAliasMyUpdate = "update XYZ set status = :newStatus";
int updatedEntities = getSession().createQuery(myUpdate) //or noAliasMyUpdate
.setInt( "newStatus", 10 )
.executeUpdate();
The question is thinking in SQL, when you should be thinking in objects:
XYZ xyz = new XYZ();
xyz.setStatus(10);
getSession().merge(xyz);
Try:
Query query = getSession().createQuery("update XYZ o set o.status = 10");
query.executeUpdate();
Take a look at this also.
Session sesssion = getSession(); //getter for session
For HQL :
String hql = "update Activity " +
"set startedOn = :taskStartedOn " +
"where id = :taskId";
Query query = session.createQuery(hql);
query.setDate("taskStartedOn",new Date());
query.setLong("taskId",1)
int rowCount = query.executeUpdate();
Here Activity is POJO.
Use
hibernate.query.factory_class = org.hibernate.hql.ast.ASTQueryTranslatorFactory
in hibernate.cfg.xml file to resolve exception:
org.hibernate.QueryException: query must begin with SELECT or FROM: update.....

Categories