I have a field in SSMS which is of type nvarchar. It has date and time stored in it . I want to retrieve records which is before a date using criteria_builder. I am able to retrieve it using SQL. The Sql is given below:
SELECT CONVERT(DateTime,f.field_values,103) as DueDate
FROM TableA a
JOIN TableB p ON a.id = p.activity_id
JOIN TableC s ON p.id = s.package_id
JOIN TableD f ON s.id = f.package_section_id
WHERE a.code like '%sass%' and f.field_name='Due_Date'
However when i try to use Hibernate criteria:
I get
Conversion failed when converting date and/or time from character string.
This occurs as I m not using the SQL Convert function. I have searched a lot online but unable to find how can i use CONVERT in Hibernate criteria. Hibernate predicate I am using is:
Predicate fieldPredicates = cb.and(cb.equal(packageFieldJoin.get(TableB_.fieldName), "Due_Date"),
cb.lessThan(packageFieldJoin.get(TableB_.fieldValuesData)), sdf1.parse(CLOSE_DUE_BEFORE)))
In Hibernate 3, is there a way to do the equivalent of the following MySQL limit in HQL?
select * from a_table order by a_table_column desc limit 0, 20;
I don't want to use setMaxResults if possible. This definitely was possible in the older version of Hibernate/HQL, but it seems to have disappeared.
This was posted on the Hibernate forum a few years back when asked about why this worked in Hibernate 2 but not in Hibernate 3:
Limit was never a supported clause
in HQL. You are meant to use
setMaxResults().
So if it worked in Hibernate 2, it seems that was by coincidence, rather than by design. I think this was because the Hibernate 2 HQL parser would replace the bits of the query that it recognised as HQL, and leave the rest as it was, so you could sneak in some native SQL. Hibernate 3, however, has a proper AST HQL Parser, and it's a lot less forgiving.
I think Query.setMaxResults() really is your only option.
// SQL: SELECT * FROM table LIMIT start, maxRows;
Query q = session.createQuery("FROM table");
q.setFirstResult(start);
q.setMaxResults(maxRows);
If you don't want to use setMaxResults() on the Query object then you could always revert back to using normal SQL.
The setFirstResult and setMaxResults Query methods
For a JPA and Hibernate Query, the setFirstResult method is the equivalent of OFFSET, and the setMaxResults method is the equivalent of LIMIT:
List<Post> posts = entityManager.createQuery("""
select p
from Post p
order by p.createdOn
""")
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
The LimitHandler abstraction
The Hibernate LimitHandler defines the database-specific pagination logic, and as illustrated by the following diagram, Hibernate supports many database-specific pagination options:
Now, depending on the underlying relational database system you are using, the above JPQL query will use the proper pagination syntax.
MySQL
SELECT p.id AS id1_0_,
p.created_on AS created_2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?, ?
PostgreSQL
SELECT p.id AS id1_0_,
p.created_on AS created_2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
SQL Server
SELECT p.id AS id1_0_,
p.created_on AS created_on2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
OFFSET ? ROWS
FETCH NEXT ? ROWS ONLY
Oracle
SELECT *
FROM (
SELECT
row_.*, rownum rownum_
FROM (
SELECT
p.id AS id1_0_,
p.created_on AS created_on2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
) row_
WHERE rownum <= ?
)
WHERE rownum_ > ?
The advantage of using setFirstResult and setMaxResults is that Hibernate can generate the database-specific pagination syntax for any supported relational databases.
And, you are not limited to JPQL queries only. You can use the setFirstResult and setMaxResults method seven for native SQL queries.
Native SQL queries
You don't have to hardcode the database-specific pagination when using native SQL queries. Hibernate can add that to your queries.
So, if you're executing this SQL query on PostgreSQL:
List<Tuple> posts = entityManager.createNativeQuery(
SELECT
p.id AS id,
p.title AS title
from post p
ORDER BY p.created_on
""", Tuple.class)
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
Hibernate will transform it as follows:
SELECT p.id AS id,
p.title AS title
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
Cool, right?
Beyond SQL-based pagination
Pagination is good when you can index the filtering and sorting criteria. If your pagination requirements imply dynamic filtering, it's a much better approach to use an inverted-index solution, like ElasticSearch.
If you don't want to use setMaxResults, you can also use Query.scroll instead of list, and fetch the rows you desire. Useful for paging for instance.
You can easily use pagination for this.
#QueryHints({ #QueryHint(name = "org.hibernate.cacheable", value = "true") })
#Query("select * from a_table order by a_table_column desc")
List<String> getStringValue(Pageable pageable);
you have to pass new PageRequest(0, 1)to fetch records and from the list fetch the first record.
You need to write a native query, refer this.
#Query(value =
"SELECT * FROM user_metric UM WHERE UM.user_id = :userId AND UM.metric_id = :metricId LIMIT :limit", nativeQuery = true)
List<UserMetricValue> findTopNByUserIdAndMetricId(
#Param("userId") String userId, #Param("metricId") Long metricId,
#Param("limit") int limit);
String hql = "select userName from AccountInfo order by points desc 5";
This worked for me without using setmaxResults();
Just provide the max value in the last (in this case 5) without using the keyword limit.
:P
My observation is that even you have limit in the HQL (hibernate 3.x), it will be either causing parsing error or just ignored. (if you have order by + desc/asc before limit, it will be ignored, if you don't have desc/asc before limit, it will cause parsing error)
If can manage a limit in this mode
public List<ExampleModel> listExampleModel() {
return listExampleModel(null, null);
}
public List<ExampleModel> listExampleModel(Integer first, Integer count) {
Query tmp = getSession().createQuery("from ExampleModel");
if (first != null)
tmp.setFirstResult(first);
if (count != null)
tmp.setMaxResults(count);
return (List<ExampleModel>)tmp.list();
}
This is a really simple code to handle a limit or a list.
Criteria criteria=curdSession.createCriteria(DTOCLASS.class).addOrder(Order.desc("feild_name"));
criteria.setMaxResults(3);
List<DTOCLASS> users = (List<DTOCLASS>) criteria.list();
for (DTOCLASS user : users) {
System.out.println(user.getStart());
}
Below snippet is used to perform limit query using HQL.
Query query = session.createQuery("....");
query.setFirstResult(startPosition);
query.setMaxResults(maxRows);
You can get demo application at this link.
You can use below query
NativeQuery<Object[]> query = session.createNativeQuery("select * from employee limit ?");
query.setparameter(1,1);
#Query(nativeQuery = true,
value = "select from otp u where u.email =:email order by u.dateTime desc limit 1")
public List<otp> findOtp(#Param("email") String email);
I have the following query which runs perfectly in mysql.
SELECT * FROM Orders as o, Products as p where o.productinfo RLIKE p.code;
Here I am joining two tables Orders and Products with RLIKE.
I am trying to implement the same in Hibernate.
Query query = session.createQuery("FROM Orders as o, Products as p where o.productinfo RLIKE p.code");
List<Object[]> results = query.getResultList();
When I used RLIKE, the following error is thrown in run time.
{"errormessage":"org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: RLIKE
I tried to implement the same with LIKE query and matched it with '%p.code%'.
Query query = session.createQuery("FROM Orders as o, Products as p where o.productinfo LIKE '%p.code%'");
But it matches with the string "p.code" rather then the value.
What is the equivalent of RLIKE in HQL?
Is there a different way to join two tables with LIKE in HQL?
Thanks.
Answer by #YCF_L:
For any one trying to join two tables with like operator in Hibernate (mysql) can do it the following way.
SELECT * FROM Orders as o, Products as p where o.productinfo LIKE CONCAT('%',p.code,'%');
What's the equivalent of mysql RLIKE operator in Hibernate Query?
RLIKE is the synonym for REGEXP so you can implement it in hibernate using REGEXP_LIKE, you can take a look about this here : How to search in multiple columns using one like operator in HQL (hibernate sql)
I tried to implement the same with LIKE query and matched it with
'%p.code%'.
..., Products as p where o.productinfo LIKE '%p.code%'");
But it matches with the string "p.code" rather then the value.
This is true, because you don't pass the correct value of p.code, you pass it like a String, instead you have two ways :
Query query = session.createQuery("....Products as p where o.productinfo LIKE '%:code%'");
//------------------------------------------------------------------------------^^^^^^^
query.setParameter("code", p.code);
Or you can concatenate your code with your Query, but the first solution is better.
Query query = session.createQuery(".... where o.productinfo LIKE '%" + p.code + "%'");
EDIT
You can use like with CONCAT without specify the '' like this :
SELECT * FROM Orders as o, Products as p where o.productinfo LIKE CONCAT('%',p.code,'%');
You can check regular expression way something like this way: Restrictions.sqlRestriction(word REGEXP '^[A-Z][A-Za-z]*$')
Please check the link which will be helpful for this case: Regular expression with criteria
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
I am trying to get distinct values from table application based on the column entry_id. I've managed to get this working with plain SQL:
SELECT DISTINCT ON (a.entry_id) a.* FROM application AS a
JOIN entry AS e ON e.id = a.entry_id
WHERE e.valid_until BETWEEN ? AND ?;
The problem is, I have to translate it to HQL. Is there any way to resolve it in HQL without Criteria API?
It looks like this feature has been requested a long time ago but is still unresolved.