JPA and Hibernate - Criteria vs. JPQL or HQL

What are the pros and cons of using Criteria or HQL? The Criteria API is a nice object-oriented way to express queries in Hibernate, but sometimes Criteria Queries are more difficult to understand/build than HQL.

When do you use Criteria and when HQL? What do you prefer in which use cases? Or is it just a matter of taste?


Asked by: Thomas671 | Posted: 28-01-2022






Answer 1

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.

Answered by: Daniel622 | Posted: 01-03-2022



Answer 2

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.

Regarding fetching strategies [http://www.hibernate.org/315.html]

  • Criteria respects the laziness settings in your mappings and guarantees that what you want loaded is loaded. This means one Criteria query might result in several SQL immediate SELECT statements to fetch the subgraph with all non-lazy mapped associations and collections. If you want to change the "how" and even the "what", use setFetchMode() to enable or disable outer join fetching for a particular collection or association. Criteria queries also completely respect the fetching strategy (join vs select vs subselect).
  • HQL respects the laziness settings in your mappings and guarantees that what you want loaded is loaded. This means one HQL query might result in several SQL immediate SELECT statements to fetch the subgraph with all non-lazy mapped associations and collections. If you want to change the "how" and even the "what", use LEFT JOIN FETCH to enable outer-join fetching for a particular collection or nullable many-to-one or one-to-one association, or JOIN FETCH to enable inner join fetching for a non-nullable many-to-one or one-to-one association. HQL queries do not respect any fetch="join" defined in the mapping document.

Answered by: Walter955 | Posted: 01-03-2022



Answer 3

Criteria is an object-oriented API, while HQL means string concatenation. That means all of the benefits of object-orientedness apply:

  1. All else being equal, the OO version is somewhat less prone to error. Any old string could get appended into the HQL query, whereas only valid Criteria objects can make it into a Criteria tree. Effectively, the Criteria classes are more constrained.
  2. With auto-complete, the OO is more discoverable (and thus easier to use, for me at least). You don't necessarily need to remember which parts of the query go where; the IDE can help you
  3. You also don't need to remember the particulars of the syntax (like which symbols go where). All you need to know is how to call methods and create objects.

Since HQL is very much like SQL (which most devs know very well already) then these "don't have to remember" arguments don't carry as much weight. If HQL was more different, then this would be more importatnt.

Answered by: First Name532 | Posted: 01-03-2022



Answer 4

I usually use Criteria when I don't know what the inputs will be used on which pieces of data. Like on a search form where the user can enter any of 1 to 50 items and I don't know what they will be searching for. It is very easy to just append more to the criteria as I go through checking for what the user is searching for. I think it would be a little more troublesome to put an HQL query in that circumstance. HQL is great though when I know exactly what I want.

Answered by: Chester662 | Posted: 01-03-2022



Answer 5

HQL is much easier to read, easier to debug using tools like the Eclipse Hibernate plugin, and easier to log. Criteria queries are better for building dynamic queries where a lot of the behavior is determined at runtime. If you don't know SQL, I could understand using Criteria queries, but overall I prefer HQL if I know what I want upfront.

Answered by: Abigail818 | Posted: 01-03-2022



Answer 6

Criteria API

Criteria API is better suited for dynamically generated queries. So, if you want to add WHERE clause filters, JOIN clauses, or vary the ORDER BY clause or the projection columns, then the Criteria API can help you generate the query dynamically in a way that also prevents SQL Injection attacks.

On the other hand, Criteria queries are less expressive and can even lead to very complicated and inefficient SQL queries.

JPQL and HQL

JPQL is the JPA standard entity query language while HQL extends JPQL and adds some Hibernate-specific features.

JPQL and HQL are very expressive and resemble SQL. Unlike Criteria API, JPQL and HQL make it easy to predict the underlying SQL query that's generated by the JPA provider. It's also much easier to review one's HQL queries than Criteria ones.

It's worth noting that selecting entities with JPQL or Criteria API makes sense if you need to modify them. Otherwise, a DTO projection is a much better choice.

Conclusion

If you don't need to vary the entity query structure, then use JPQL or HQL. If you need to change the filtering or sorting criteria or change the projection, then use Criteria API.

However, just because you are using JPA or Hibernate, it doesn't mean you should not use native SQL. SQL queries are very useful and JPQL and Criteria API are not a replacement for SQL.

Answered by: Tara111 | Posted: 01-03-2022



Answer 7

Criteria are the only way to specify natural key lookups that take advantage of the special optimization in the second level query cache. HQL does not have any way to specify the necessary hint.

You can find some more info here:

Answered by: Aldus714 | Posted: 01-03-2022



Answer 8

Criteria Api is one of the good concept of Hibernate. according to my view these are the few point by which we can make difference between HQL and Criteria Api

  1. HQL is to perform both select and non-select operations on the data, but Criteria is only for selecting the data, we cannot perform non-select operations using criteria.
  2. HQL is suitable for executing Static Queries, where as Criteria is suitable for executing Dynamic Queries
  3. HQL doesn’t support pagination concept, but we can achieve pagination with Criteria.
  4. Criteria used to take more time to execute than HQL.
  5. With Criteria we are safe with SQL Injection because of its dynamic query generation but in HQL as your queries are either fixed or parametrized, there is no safe from SQL Injection

Answered by: Chelsea946 | Posted: 01-03-2022



Answer 9

To use the best of both worlds, the expressivity and conciseness of HQL and the dynamic nature of Criteria consider using Querydsl.

Querydsl supports JPA/Hibernate, JDO, SQL and Collections.

I am the maintainer of Querydsl, so this answer is biased.

Answered by: Cherry790 | Posted: 01-03-2022



Answer 10

For me Criteria is a quite easy to Understand and making Dynamic queries. But the flaw i say so far is that It loads all many-one etc relations because we have only three types of FetchModes i.e Select, Proxy and Default and in all these cases it loads many-one (may be i am wrong if so help me out :))

2nd issue with Criteria is that it loads complete object i.e if i want to just load EmpName of an employee it wont come up with this insted it come up with complete Employee object and i can get EmpName from it due to this it really work bad in reporting. where as HQL just load(did't load association/relations) what u want so increase performance many times.

One feature of Criteria is that it will safe u from SQL Injection because of its dynamic query generation where as in HQL as ur queries are either fixed or parameterised so are not safe from SQL Injection.

Also if you write HQL in ur aspx.cs files, then you are tightly coupled with ur DAL.

Overall my conclusion is that there are places where u can't live without HQL like reports so use them else Criteria is more easy to manage.

Answered by: Daryl307 | Posted: 01-03-2022



Answer 11

For me the biggest win on Criteria is the Example API, where you can pass an object and hibernate will build a query based on those object properties.

Besides that, the criteria API has its quirks (I believe the hibernate team is reworking the api), like:

  • a criteria.createAlias("obj") forces a inner join instead of a possible outer join
  • you can't create the same alias two times
  • some sql clauses have no simple criteria counterpart (like a subselect)
  • etc.

I tend to use HQL when I want queries similar to sql (delete from Users where status='blocked'), and I tend to use criteria when I don't want to use string appending.

Another advantage of HQL is that you can define all your queries before hand, and even externalise them to a file or so.

Answered by: Wilson668 | Posted: 01-03-2022



Answer 12

Criteria api provide one distinct feature that Neither SQL or HQL provides. ie. it allows compile time checking of a query.

Answered by: Anna627 | Posted: 01-03-2022



Answer 13

We used mainly Criteria in our application in the beginning but after it was replaced with HQL due to the performance issues.
Mainly we are using very complex queries with several joins which leads to multiple queries in Criteria but is very optimized in HQL.
The case is that we use just several propeties on specific object and not complete objects. With Criteria the problem was also string concatenation.
Let say if you need to display name and surname of the user in HQL it is quite easy (name || ' ' || surname) but in Crteria this is not possible.
To overcome this we used ResultTransormers, where there were methods where such concatenation was implemented for needed result.
Today we mainly use HQL like this:

String hql = "select " +
            "c.uuid as uuid," +
            "c.name as name," +
            "c.objective as objective," +
            "c.startDate as startDate," +
            "c.endDate as endDate," +
            "c.description as description," +
            "s.status as status," +
            "t.type as type " +
            "from " + Campaign.class.getName() + " c " +
            "left join c.type t " +
            "left join c.status s";

Query query =  hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();

so in our case the returned records are maps of needed properties.

Answered by: Justin969 | Posted: 01-03-2022



Answer 14

  • HQL is to perform both select and non-select operations on the data, but Criteria is only for selecting the data, we cannot perform non-select operations using criteria
  • HQL is suitable for executing Static Queries, where as Criteria is suitable for executing Dynamic Queries
  • HQL doesn’t support pagination concept, but we can achieve pagination with Criteria
  • Criteria used to take more time to execute then HQL
  • With Criteria we are safe with SQL Injection because of its dynamic query generation but in HQL as your queries are either fixed or parametrized, there is no safe from SQL Injection.

source

Answered by: Rafael673 | Posted: 01-03-2022



Answer 15

Criteria query for dynamically we can construct query based on our inputs..In case of Hql query is the static query once we construct we can't change the structure of the query.

Answered by: William684 | Posted: 01-03-2022



Answer 16

I don't want to kick a dead horse here, but it is important to mention that Criteria queries are now deprecated. Use HQL.

Answered by: Paul430 | Posted: 01-03-2022



Answer 17

I also prefer Criteria Queries for dynamic queries. But I prefer hql for delete queries, for example if delete all records from child table for parent id 'xyz', It is easily achieved by HQL, but for criteria API first we must fire n number of delete query where n is number of child table records.

Answered by: Arthur721 | Posted: 01-03-2022



Answer 18

Most the answers here are misleading and mention that Criteria Queries are slower than HQL, which is actually not the case.

If you delve deep and perform some tests you will see Criteria Queries perform much better that regular HQL.

And also with Criteria Query you get Object Oriented control which is not there with HQL.

For more information read this answer here.

Answered by: Adrian939 | Posted: 01-03-2022



Answer 19

There is another way. I ended up with creating a HQL parser based on hibernate original syntax so it first parse the HQL then it could dynamically inject dynamic parameters or automatically adding some common filters for the HQL queries. It works great!

Answered by: Dainton663 | Posted: 01-03-2022



Answer 20

This post is quite old. Most answers talk about Hibernate criteria, not JPA criteria. JPA 2.1 added CriteriaDelete/CriteriaUpdate, and EntityGraph that controls what exactly to fetch. Criteria API is better since Java is OO. That is why JPA is created. When JPQL is compiled, it will be translated to AST tree(OO model) before translated to SQL.

Answered by: Tara918 | Posted: 01-03-2022



Answer 21

Another point is that, I see Criteria is more suited for building on top of it and not to be used ditectly in the end-code.

It is more suited to build liberaries using it more than using jpql or hql.

For example I've build spring-data-jpa-mongodb-expressions using Criteria API (the same way spring data QBE do).

I think spring data query generations are using jpaql rather criteria which I don't understand why.

Answered by: Miranda925 | Posted: 01-03-2022



Answer 22

HQL can cause security concerns like SQL injection.

Answered by: Thomas261 | Posted: 01-03-2022



Similar questions

java - How to reuse a Criteria object with hibernate?

I'm trying to do query result pagination with hibernate and displaytag, and Hibernate DetachedCriteria objects are doing their best to stand in the way. Let me explain... The easiest way to do pagination with displaytag seems to be implementing the PaginatedList interface that has, among others, the following methods: /* Gets the total number of results. */ int getFullListS...


java - How to get SQL from Hibernate Criteria API (*not* for logging)

Is there a way to get the (to-be-generated) SQL from a Hibernate Criteria? Ideally, I would have something like: Criteria criteria = session.createCriteria(Operator.class); ... build up the criteria ... ... and then do something like ... String sql = criteria.toSql() (But this of course does not exist) The idea would then be to use the SQL as part of a huge 'MINUS' ...


java - Remote Hibernate Criteria

I have multiple services which call on my database service, which uses Hibernate, and I would like the remote services to be able to create a query and then pass that to be processes. Ideally I would like to pass a Criteria Object but it looks like it needs a Session which they won't have access to. Is there a process similar to the Criteria Object I could use?


java - How use hibernate criteria for a left outer join without direct link into the two tables

I'm trying to translate a SQL quest into Hibernate criteria. My quest is working in SQL : select * from objective left outer join conditionstate on objective.conditionid = conditionstate.conditionid and conditionstate.personid = XXXX where objective.toto_id = YYYYY The objective is not directly mapped to the condition_state, but into a condition....


java - tricky hibernate criteria

I have a sql statement which I want to move it into hibernate criteria, but I am not clue how to do this. The problem is one of the WHERE clause which looks like the following ...(skip other parts)... ? ILIKE strprefix||'%' ...(continue) strprefix is the column name, the ? is the place i need to fill in the value. With criteria, I can use criter...


java - Hibernate criteria question

I have following POJO`s: - Company Node (nodeID, company) User (userID, node) I want to create where clause(via Criteria) which will return to me every user for given company. Something like ... Criteria criteria = session.createCriteria(User.class) criteria.add(Restrinctions.eq("node.company", someCompanyObject); But this is not working,...


java - Some help with hibernate Criteria query

Can somebody please help me complete / clean up this query. I am trying to first get the number of rows in the table, then I need to actually fetch a set of rows. I am not sure how I can use the same criteria instance to perform both queries. To fetch the count I have something like this: Criteria criteria = session.createCriteria(MyTable.class); criteria.setProjection(Projections.rowCount()); Int...


java - Hibernate Criteria and multiple join

is possible with Hibernate criteria do it? select A.something, B.something, C.something, D.something from A JOIN B on A.id = B.id_fk JOIN C ON B.id = C.id_fk JOIN D ON C.id = D.id_fk;


java - Hibernate criteria -- alias

I'm struggling a bit with the concept of alias in Hibernate. My situation is the following: Order @OneToMany(cascade=CascadeType.ALL,mappedBy="m_order") private Set<OrderDetail> m_details; OrderDetail @ManyToOne(cascade=CascadeType.ALL) @JoinColumn(name="product_id") private Product m_product; @ManyToOne(casca...


java - Hibernate Criteria API: get n random rows

I can't figure out how to fetch n random rows from a criteria instance: Criteria criteria = session.createCriteria(Table.class); criteria.add(Restrictions.eq('fieldVariable', anyValue)); ... Then what? I can't find any doc with Criteria API Does it mean I should use HQL instead? Thanx! EDIT: I get the number of rows by: int max = criteria.setProjecx...


java - Hibernate returns invalid results with composite key

I'm getting the strangest results. I have a class with a composite key. If i do the following query: from LOVEJB l order by l.canonicalId desc my results are not ordered by the 'canonicalId' column I asked for. Instead, the canonical id result is like: 823 823 822 823 ,,, Can someone give me some pointers on how sho...


java - Audit Schema Mapping with Hibernate and AOP

I am trying to audit the action that the user performed that resulted in changes to corresponding tables. For example if a user were to transfer money between 2 accounts this would generate the following sequence of events: Insert transfer amount into Transfer table Subtract transfer amount from balance in Balance Table for Account 1. Add transfer amount to balance in Balance Table for Accou...


java - Hibernate and Oracle native functions

I have an entity that maps to an external oracle table which is one of the primary data sources of my application. This entity is modelled using hibernate. The oracle table now has a complex function defined the calculates some special values. I need to call this function somehow - almost as another accessor on the entity. What would you suggest is the best way to incorporate this function call so that I ca...


java - How to get distinct results in hibernate with joins and row-based limiting (paging)?

I'm trying to implement paging using row-based limiting (for example: setFirstResult(5) and setMaxResults(10)) on a Hibernate Criteria query that has joins to other tables. Understandably, data is getting cut off randomly; and the reason for that is explained


java - Hibernate group by time interval

I have a table with a timestamp field of type datetime. I need to aggregate the data between a defined start and end time into x groups representing time intervals of equal length, where x is supplied as function parameter. What would be the best way to do this with Hibernate? EDIT: some explanations mysql Table: data_ts: datetime pk value1 : int value2 : bigint ...


java - How do I use Hibernate from an Eclipse Plug-in?

I am writing an Eclipse plug-in that loads resources from a central database. I would like to use Hibernate to access that database. So how would I add this as a dependency to my plug-in project? I've tried Google but only get hits on about plug-ins for editing Hibernate configuration fil...


java - How do I ensure a value being updated with Hibernate hadn't been changed in the meantime since I read it?

I have a problem where I want to read an object from the database using Hibernate, change a value, and save the object. If changing the value takes some time, what's the best way to ensure the underlying object in the database has not changed? I am doing this in one transaction (and one session). The code looks something like: // Load from DB Criteria crit = session.createCriteria( Dummy.class ).a...


java - How do I map a hibernate Timestamp to a MySQL BIGINT?

I am using Hibernate 3.x, MySQL 4.1.20 with Java 1.6. I am mapping a Hibernate Timestamp to a MySQL TIMESTAMP. So far so good. The problem is that MySQL stores the TIMESTAMP in seconds and discards the milliseconds and I now need millisecond precision. I figure I can use a BIGINT instead of TIMESTAMP in my table and convert the types in my Java code. I'm trying to figure out if there is a better way of doing this using ...


java - How to reuse a Criteria object with hibernate?

I'm trying to do query result pagination with hibernate and displaytag, and Hibernate DetachedCriteria objects are doing their best to stand in the way. Let me explain... The easiest way to do pagination with displaytag seems to be implementing the PaginatedList interface that has, among others, the following methods: /* Gets the total number of results. */ int getFullListS...


java - Hibernate and currency precision

I have a hibernate mapping as follows: <hibernate-mapping> <class name="kochman.elie.data.types.InvoiceTVO" table="INVOICE"> <id name="id" column="ID"> <generator class="increment"/> </id> <property name="date" column="INVOICE_DATE"/> <property name="customerId" column="CUSTOMER_ID"/> <property nam...






Still can't find your answer? Check out these amazing Java communities for help...



Java Reddit Community | Java Help Reddit Community | Dev.to Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)



top