Criteria API - Hibernate vs JPA 2

Asked

Viewed 2,459 times

11

I will try to phrase this question in the least opinionated way possible in the spirit of stackoverflow in English. For a new project I need to make the decision between using the JPA 2 or Hibernate API (while it is technically possible to mix the two, for architectural reasons we will have to choose between one or the other).

I have a team of Hibernate-versed developers who know a lot about HQL and the native Criteria API.

Particularly as someone who read the book Pro JPA 2 from end to end, I think that JPQL is sufficiently similar to HQL so that the transition is not problematic.

On the side of the Criteria API, which is widely used by developers, the difference is much more significant. While the JPA 2 API seems much more powerful than the Hibernate API it has a learning curve for developers: metamodel, strongly typed queries, etc.

The positive side is that in addition to making the project independent of the ORM provider, the new API has several Features useful as clause support having (open problem at Ibernate since 2005 that always brought us headaches).

My question then is. Are any of you using the JPA 2 Criteria API on large projects? Someone who has experience with both Apis could make a comparison of the pros and cons of each?

  • The problem with this type of question is not because it is opinionated, but because the answers will be more based on opinions. The question is a kind of poll, which is not very appropriate for the OS format.

  • Having said that, there is an aphorism that says, "when you are finding it very difficult to choose between two things, it is probably not a very important decision". I think it applies in this case: the decision between JPA2 and Hibernate will probably not impact much on the success/failure of the big project. =)

  • I know almost zero on the subject itself, but it seems that the question is seeking information objectively and the first answer seems to be well elaborated. The line is thin but can work. Anyway, when doubts arise, it is always good to reflect if it can be improved.

2 answers

10


Choosing which API to use would not only be a choice of hand in the code, but you should also think about architecture. I’ll describe what I think about you two:

Considerations on architecture

The advantage of using the native JPA Criteria API is that:

  1. You will have more flexibility to change implementation, you will be able to keep the JPA code used. As only the interfaces of JPA will be used, both as Eclipse, Openjpa, Hibernate, etc will have these interfaces implemented.
  2. Any new Eature you add in a new version, you will already have access
  3. You have the option to use the criteria in typed mode or not, the typed mode already shows error at compile time
  4. Allows complex queries to be performed, and if there is an error in the implementation (Hibernate for example), just make a portability of Provider (go to Eclipselink for example)

The downside of using the native JPA API is:

  1. Complexity. Due to the large number of classes that exist in the native API, knowing all and your goals will take a long time
  2. Verbosity. It’s a very verbose API, a simple command like select leads to multiple lines of code

The advantage of using the Hibernate Criteria API is that:

  1. Simple and easy to use code
  2. Have access to features that will not be present in the native API

The drawback of using the Hibernate Criteria API is that:

  1. You will be stuck with an implementation. If any problems occur with Hibernate you will have problems migrating to another implementation. Some time ago, for example, Batoo was released that promised a performance 15x faster than Hibernate. Imagine that your project is having performance problems and you would like to test this new implementation? When using Hiberate API this test would take a long time. Already with JPA native API would be done faster.
  2. Artifact Size. Unfortunately Hibernate has many dependencies, with this, the size of War/Ear increases considerably. This could be a problem when uploading the artifact to the production environment does not have a good internet link.

Considerations on the Code

See how a select * from person (Entity Person) will look when using the JPA criteria:

CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<Person> root = criteriaQuery.from(Person.class);
criteriaQuery.select(root); // necessário caso uma condição where seja adicionada na consulta
TypedQuery<Person> query = entityManager.createQuery(criteriaQuery);
query.getResultList();

Several lines of code to perform a simple query. As said, the complexity and verbosity are unfortunately large. See how the same query will look above using Hibernate:

Criteria criteria = session.createCriteria(Person.class);
List persons = criteria.list();

Note that the code became much smaller and simpler to execute, only that there was the addition of the code of Hibernate itself.


What to choose?

Some questions could be asked to decide which criteria to use:

  1. What level of staff will maintain the project?
  2. It is possible that a small training in criteria will be given to the whole team?
  3. My project may have very complex queries using criteria?
  4. The project may have performance problems?

There are solutions to use native API?

There are frameworks on the market that work with the native JPA API and facilitate the use of the criteria. One of them is Easycriteria (http://easycriteria.uaihebert.com/). The same queries held above could be done as below:

EasyCriteria<Person> easyCriteria = EasyCriteriaFactory.createQueryCriteria(entityManager, Person.class);
easyCriteria.getResultList();

The advantage of using this type of framework is that it would be possible to migrate from Hibernate to Openjpa, for example.

Another solution would be Querydsl, which also has an interface to facilitate the consultation and creation of typed criterias (I don’t know if typed criterias work). In this case you would generate a meta model and then use Querydsl to generate the criteria.

  • I also see the problem more as a matter of architecture than of taste, both solutions are good, and I see that the choice for JPA has more advantages than the choice for Hibernate.

  • Honestly until today I always used pure JPA and never missed Hibernate, except for the criteria. [=

4

I will try to respond objectively, but also by analysing technology choices in general terms.

About API Choices

Firstly, the idea of supplier independence that several Apis sell is tempting but in most cases it hardly occurs. Take the case of application servers, for example. Can anyone do the distribution of the same WAR in a Tomcat, Jboss, Glassfish or Weblogic? Each contains specific features that vary immensely from one to the other. On the other hand, if you completely ignore the features of your application server, you will lose the advantages of using it.

In practice, you should choose from the options available that seem to best meet the requirements of your project without spending too much time on it, as it is probably not worth going into too much detail when it comes to mature and commonly used products on the market. Of course there will be wrong choices and this is a real risk, so here counts much the experience and experience of the team and the leader.

Hibernate or JPA?

Speaking now specifically of JPA and Hibernate, I can say that JPA has really made great strides, but sometimes you may need a unique Hibernate feature, like Dynamic Queries or User Types (Update: Hibernate 4.3 implements the JPA 2.1 specification and has the annotation @Converter, so it is no longer necessary to resort to a User Type to map an enum or non-standard type. Anyway, the important thing is the idea represented in the text.).

Which to choose then? The answer is: neither one nor the other. You can use both Apis at the same time. As a suggestion, JPA might have preference, but the Hibernate API would be used when needed. Particularly I had no trouble doing that.

Example #1 of Hibernate + JPA: Dynamic queries

Using a dynamic query allows not including null fields in commands like INSERT, for example, so that the value default database will be used. In Hibernate this can be done through XML mapping or annotations @org.hibernate.annotations.Entity and @DynamicInsert (in the latest versions).

But, suppose you already have a persistence.xml and a JPA entity as below:

@javax.persistence.Entity
public class MinhaEntidade { ... }

Now what? Just add the Hibernate note:

@org.hibernate.annotations.Entity
@org.hibernate.annotations.Entity(dynamicInsert = true)
public class MinhaEntidade { ... }

Example #2 of Hibernate + JPA: Session Access

What if you have some HQL feature that would greatly enhance one of the features? No problem, just unpack the Sessionhibernate:

Session session = entityManager.unwrap(Session.class);

Impact of this approach

Obviously, following these examples, the implementation would be "tied" to Hibernate.

However, the impact of a change, which I believe there will always be, will be minimized to some specific functionalities.

Finally, what’s the chance real that you need to trade Hibernate for another JPA implementation in the near future? I don’t mean to say that Hibernate is absolutely superior, but the odds are slim that someone really needs a resource that only exists, let’s say, in Eclipselink, and there is none workaround available.

  • 1

    yesterday I read this post and found it quite interesting, but when you refer to userType of Hibernate, yesterday while searching on google it seems that recently launched a annotation @converter to implement in a class something similar to Hibernate. link

  • 1

    @Macario1983 JPA is constantly evolving and many of the features specific to one of the implementations are being incorporated (modified, of course), into the standard. Version 2.1 of JPA actually has the annotation @Converter. In this sense my statement is out of date. However, Hibernate only released the JPA 2.1 implementation a few months ago and has a lot of people tied up with old versions. Anyway, thank you for the information.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.