Function sum with HQL language - java

I have a question (sorry about my English, I'm learning)!
I searched everywhere for how to use the command sum(column) with HQL hibernate language, but I can't find anything!
I can do it with SQL language. Example:
SELECT sum(Column) FROM tablethatIwantthevalues;
but not with HQL Hibernate!

You can use same query as SQL, try below solution :
Session s = OptimazPoolM.getSessionFactory().openSession();
String sumHql = "SELECT SUM(salary) FROM employees WHERE idemployee = 31";
Query sumQuery = s.createQuery(sumHql);
System.out.println(sumQuery.list().get(0));

You can use aggregation functions in HQL as well as in SQL, take a look at the Hibernate Query Language Manual: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-aggregation

Related

Avoid SQL Injection in Spring JPA

I am using sql query like
String query = "Select max(case when UPPER(key)='firstname' then value end) as firstNameName, , ... order by "+orderBy;
result = em.createNativeQuery(query).getResultList();
em.close();
for some reason i would have to use dynamic +orderBy . Where orderBy =firstname ASC , lastname DESC etc. Tried using .setParameter(1, orderedBy) but in this case i am not getting expected ordered results.
For avoiding sql injection threats you firstly need to remove appending parameters to your query. When you're appending parameters in your app, the atacker can hijack your sql code (with apostrophes and other means for example)
For example:
If your query is "select * from table where name="+id
The attacker can pass to the field values such as:
'John' or 1=1; ->sees all your records in this table
Or even
'John' or 1=1;Delete all from users;' -> deleting all entries from users table.
Hijacking queries can be avoided via mechanisms such as input sanitization, input whitelisting/blacklisting(removing unwanted characters from the input/ defining a list of allowed or unnalowed characters). Most modern framerowks such as JDBC/JPA/Hibernate can offer protection from this threat.
With all this stated we should take into consideration the following scenarios:
Considering sql where parameters:
JDBC for example offers prepared statements, where you define a variable in your sql, and the framework replaces it
In your case a JPA implementation(Hibernate) also has mechanisms for avoiding this threat, also via parameterized queries and positional paramaters:
via native query positional parameters:
Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1");
q.setParameter(1, "test");
via named parameters(jplq)
Query q = em.createQuery("SELECT count(*) FROM mytable where username = :username");
q.setParameter("username", "test");
Considering orderBy parameters:
CriteriaQuery/spring Specifications
CriteriaBuilder cb = this.entityManager
.getCriteriaBuilder();
CriteriaQuery<RESULT> criteria = cb.createQuery(RESULT.class);
Root<RESULT> root = criteria.from(RESULT.class);
return this.entityManager.createQuery(
criteria.select(root).orderBy(cb.asc(root.get("ORDER_BY_FIELD"))))
.getResultList();
More on criteriaQueries usage and config here
Passing orderBy via spring specific Sort parameter built beforehand(using the spring-data library)
Sort sort = Sort.by(Sort.Direction.ASC, "criteria");
em.createQuery(QueryUtils.applySorting(yourSqlQuery_withoutSorting,sort));
annotate method with #Query with spring-data library:
You can achieve the same result with less boiler plate code(without injecting an entityManager and creating a nativeQuery) by just annotating a method with a #Query annotation:
#Query("select u from User u where u.lastname like ?1%")
List<User> findByAndSort(String lastname, Sort sort);
Note:
Native vs non-native(jpql):
JOQL queries are independent of the database vendor(MySQL,PostGres,Oracle,DB2), nativeQueries usages are more focused when you need to use a database specific functionalities which differes accross vendors.
For a brief example jpql can not support native [With]2 clause PLSQL standard functions
Regarding your edit:
You can try to apply the following sql trick for dynamic ordering:
SELECT param1, param2 ...
FROM ...
ORDER BY case when :sortParam='name asc' then name asc END
case when :sortParam='name desc' then name desc END
....
else 0

Spring data date between query

I have a query like below:
select * from Products p where ? between p.effctDate and p.expDate
Can I translate the above query to a spring data jpa query method? Like for example:
findByProductId(productId)
or I only have to use #Query or a Named query to handle such types of queries. I tried searching here first before asking the question as well as spring data site but did not find any solution. any help is appreciated.
You could use the following query:
Date date = //Input date
List<Product> = findByEffctDateAfterAndExpDateBefore(date, date);
Note that you have to enter date twice to match both 'where' clauses. This is under the assumption you are using Date objects, not literal Strings.
See JPA Repositories Table 2.3 for more info.
You can try to use something like below :
List findAllByDateApprovedBetween(String dateApprovedFrom, String dateApprovedTo);
It translates to :
Hibernate: select applicatio0_.id as id1_1_, applicatio0_.date_approved as date_app4_1_ from application applicatio0_ where (applicatio0_.date_approved between ? and ?)
You can try something like this trick:
select
p
from
Product p
where
(?1 = 'field1' and p.field1 between p.effctDate and p.expDate)
or (?1 = 'field2' and p.field2 between p.effctDate and p.expDate)
or (?1 = 'field3' and p.field3 between p.effctDate and p.expDate)
or (?1 = 'field4' and p.field4 between p.effctDate and p.expDate)
...
But this is not the best approach IMO...
To build dynamic queries you can use thees ones:
Specifications
Query by Example
Querydsl Extension

Criteria Query returnig all records

SQL :
String hql1 = "SELECT /* PARALLEL(MVR,16) PARALLEL(MVRS,16)*/ * FROM
ICM MINUS SELECT I1.* FROM ICM I1 , C1_ICM_STATIC I2 WHERE
I1.METRIC_DIRECTION=I2.METRIC_DIRECTION AND
I1.METRIC_NAME=I2.METRIC_NAME AND I1.METRIC_UNIT=I2.METRIC_UNIT AND
I1.TERMINATION_POINT_ID=I2.TERMINATION_POINT_ID AND
I1.TERMINATION_POINT_NAME=I2.TERMINATION_POINT_NAME AND
I1.TERMINATION_POINT_TYPE=I2.TERMINATION_POINT_TYPE";
Criteria Query
icms1 = (List<ICM>) session.createCriteria(ICM.class, hql1).list();
I have executed hql1 using SQL Developer then I got only one result, but when I have integrated SQL Query with Criteria it returning me all records in ICM table.
If SQL query returning only one result in SQL Developer, Why criteria API returning all records in ICM table?
Why criteria API returning all records in ICM table?
Technically you are not using criteria api for associations.
Try something like this.
Refer.
return criteria.createCriteria(A.class)
.createCriteria("b", "join_between_a_b")
.createCriteria("c", "join_between_b_c")
.createCriteria("d", "join_between_c_d")
.add(Restrictions.eq("some_field_of_D", someValue));
You should learn to read API documentation.
The second Session.createCriteria() argument is the alias that you want to assign to the root entity. It's not a HQL query. HQL queries are not executed using Session.createCriteria(). They're executed using Session.createQuery().
BTW, your query is not a HQL query at all. It's a SQL query. SQL and HQL are 2 different languages. To execute a SQL query, you need createSQLQuery().

Select distinct year from date using Hibernate Criteria

I would like to get all distinct years from a MySQL date field with the Hibernate Criteria API. This is the query that I want to translate to criteria:
sess.createQuery("SELECT DISTINCT year(o.date) FROM Observation");
I've tried :
Criteria crit = sess.createCriteria(Observation.class)
.setProjection(Projections.distinct(Projections.property("year(date)")));
But it returns an error
ERROR - could not resolve property: year(date) of: ca.ogsl.biodiversity.hibernate.Observation
Does any body knows if it's possible and how?
Thanks a lot!!!
Keven
Try using an sql projection, so you can use any SQL expression:
criteria.setProjection(Projections.sqlProjection( "yeard(DATE_COLUMN_NAME) as year", new String[] {"year"}, new Type[] {StandardBasicTypes.INTEGER} ));
Use the DISTINCT keyword to query for distinct years, rather than getting all years and trying to filter them in Java code.
SELECT DISTINCT year(o.date) FROM Observation;

convert sql to hql

I am performing this via sql but i want to do this in hql, select statement in from ( select count(*)...) not works in hql, any sugestion and optimization would be appreciated
SELECT u.username,u.device_tocken,sr.count
from users u,
(select count(*) as count ,ssr.recepient as res from survey_recipient ssr where
(ssr.is_read is false and ssr.recepient in ('abc','xyz'))group by ssr.recepient ) sr
where
(u.username = sr.res and u.device_tocken is not null)
Hibernate does not support subselects in from clouse.
i tried many things and gave up when i found this jira issue.
see here https://hibernate.onjira.com/browse/HHH-3356
But if you have to use subselect you can create database views and use them in your sql as normal tables.

Categories

Resources