73

I have been reading some anwers, but i'm still confused. ¿Why? because the differences that you have mentioned do not relate with the performance. they are related with easy use.(Objetc(criteria) and SQL(hql)). But I would like to know if "criteria" is slower than hql for some reason.

I read this in another anwers

"There is a difference in terms of performance between HQL and criteriaQuery, everytime you fire a query using criteriaQuery, it creates a new alias for the table name which does not reflect in the last queried cache for any DB. This leads to an overhead of compiling the generated SQL, taking more time to execute." by Varun Mehta.

This is very close BUT! i read in another website(http://gary-rowe.com/agilestack/tag/hibernate/) This is no longer the case with Hibernate 3.3 and above(please read this: 9) Hibernate is slow because the SQL generated by the Criteria interface is not consistent)

I have done some test trying to find out the differences but both generate qry's and it doesn't change the alias to the table.

I'm very confused. If somebody knows the main reason please, could you help us. Thanks

Jonik
  • 74,291
  • 66
  • 249
  • 356
kcobuntu
  • 761
  • 1
  • 6
  • 4

5 Answers5

153

I'm the guy who wrote the Hibernate 3 query translator back in 2004, so I know something about how it works.

Criteria, in theory should have less overhead than an HQL query (except for named queries, which I'll get to). This is because Criteria doesn't need to parse anything. HQL queries are parsed with an ANTLR-based parser and then the resulting AST is turned into SQL. However, with HQL/JPAQL you can define named queries, where the SQL is generated when the SessionFactory starts up. In theory, named queries have less overhead than Criteria.

So, in terms of SQL-generation overhead we have:

  1. Named HQL/JPAQL Query - SQL generation happens only once.
  2. Criteria - No need to parse before generating.
  3. (non-named) HQL/JPAQL Query - Parse, then generate.

That said, choosing a query technique based on the overhead of parsing and SQL generation is probably a mistake in my opinion. This overhead is typically very small when compared to performing a real query on a real database server with real data. If this overhead does actually show up when profiling the app then maybe you should switch to a named query.

Here are the things I consider when deciding between Criteria and HQL/JPAQL:

  • First, you have to decide if you're OK with having a dependency on Hibernate-proprietary API in your code. JPA doesn't have Criteria.
  • Criteria is really good at handling many optional search parameters such as you might find on a typical web page with a multi-parameter 'search form'. With HQL, developers tend to tack on where clause expressions with StringBuilder (avoid this!). With Criteria, you don't need to do that. Hardik posted similar opinions.
  • HQL/JPAQL can be used for most other things, because the code tends to be smaller and easier for developers to understand.
  • Really frequent queries can be turned into named queries if you use HQL. I prefer to do this later, after some profiling.
Joshua Davis
  • 3,368
  • 1
  • 24
  • 29
  • `JPA doesn't have Criteria` ? – destan Sep 28 '14 at 06:03
  • 3
    @destan As of JPA 2.x, it does. IIRC, JPA 1.x does not. – Joshua Davis Oct 15 '14 at 21:17
  • @JoshuaDavis Excellent explanation. I just want to know why we must avoid using StringBuilder to construct HQL. What to do with optional parameters, for example? – bruno.zambiazi Mar 20 '15 at 18:27
  • 2
    @bruno.zambiazi If you are building JPAQL/HQL by string concatentation, then it is very likely that you have a dynamic query and that's what the Criteria query feature is for. I tend to use Criteria for anything dynamic (e.g. the query varies a lot depending on user input). HTH - Josh – Joshua Davis Mar 20 '15 at 20:27
  • Which is most faster when joined tables? – GokulRaj K.N. Sep 20 '19 at 07:47
  • 1
    @GokulRajK.N. There should not be much difference in explicit or implicit joins when generating SQL from Criteria or JPQL. Typically, executing the joins takes far longer than generating the SQL, so switching between the two won't make a noticeable difference most of the time. – Joshua Davis Oct 23 '19 at 16:40
9

I am working on millions of record. I found HQL is much more faster than Criteria. Criteria lags a lot in performance.

If you are dealing with lot of data then go for HQL.

Rajeev
  • 139
  • 1
  • 1
  • 5
    This doesn't make much sense to me. If you have a really large data set, then most of the time is spent waiting for the database to process the query. The time it takes to generate the SQL from HQL or from Criteria is not important in that case. The only time using JPAQL named queries vs 'straight' JPAQL vs Criteria is when you are doing the same query *many* times. The size of the data set doesn't matter at all. – Joshua Davis Apr 05 '15 at 17:23
  • 2
    May be you haven't used Criteria in right way. Or have you created a new Criteria Query object for each one of your millions of records? – vinodn Sep 11 '15 at 20:39
  • 1
    Perhaps the access plan of the generated SQL is different. This does not mean is Criteria's fault. – Lluis Martinez Apr 27 '18 at 14:47
7

Other Advantages I think for Criteria over HQL:

Writing HQL makes the code messy. It doesn't look like writing clean Object Oriented Code anymore.

While writing Criteria Queries, IDE suggests us with Intellisense, so there is less chance of committing mistakes except when we write something like variable names in double quotes.

omkar sirra
  • 620
  • 8
  • 21
7

I mostly prefer Criteria Queries for dynamic queries. For example it is much easier to add some ordering dynamically or leave some parts (e.g. restrictions) out depending on some parameter.

On the other hand I'm using HQL for static and complex queries, because it's much easier to understand/read HQL. Also, HQL is a bit more powerful, I think, e.g. for different join types.

JPA and Hibernate - Criteria vs. JPQL or HQL

Community
  • 1
  • 1
Hardik Mishra
  • 14,171
  • 9
  • 58
  • 94
  • 4
    Criteria can do most of the join types that HQL can do, although sometimes it's a little awkward or hard to understand (at least in my opinion). Absolutely right about HQL being easier to read! – Joshua Davis Jan 22 '11 at 21:00
  • 1
    BTW, I'd vote for your answer... but you didn't really answer kcobuntu's question. – Joshua Davis Jan 22 '11 at 21:01
  • 27
    If you're going to copy someone else's answer you should at least mention it. Link to the original answer: http://stackoverflow.com/a/197496/980103 – Soroush Mirzaei Mar 05 '14 at 12:26
  • Well..I was a newbie and we had not many users/moderators on SO. – Hardik Mishra Jul 26 '16 at 18:08
4

You are right and not. Result list is retrieved from database or cache with the org.hibernate.loader.Loader class. When cache is not enabled, prepared statement is build using the Dialect object which is created in SessionFactoryImp. So, statements either initialized per list call. Besides, low-level query is generated automatically. Basically, it is an aid, but there may be a case when a specific query will be more effective when manually written.

Ram Patra
  • 14,608
  • 12
  • 60
  • 69
Simon
  • 113
  • 1
  • 4