JPA 1 is not good enough - java

Working in a medium size project during last 4 months - we
are using JPA and Spring - I'm quite sure that JPA is not
powerfull for projects that requires more than CRUD
screen... Query interface is poor, Hibernate doesn't
respect JPA spec all the time and lot of times I need to use
hibernate classes, annotations and config.
What do you guys think about JPA? Is it not good enough?

Well I think most of the time JPA is "good enough" but I miss the Criteria API a lot (only provided by Hibernate)

Hibernate has been a long time in the road. That's why it has many functions not avaiable in JPA yet. But with time JPA will catch up. Until then, use JPA and Hibernate specific settings where necessary. If you need to switch later, it'll be a lot easier.

Well I can't provide specific guidance without knowing more about your particular case. It seems like you're using Hibernate's JPA implementation. You might try other JPA implementations if there is something about Hibernate's you don't like. As far as the query interface, if JPA's queries aren't doing what you want, you always have the ability to get a plain old Connection and work with that. The genius of the framework is that -- at the very least -- you don't have to write all the CRUD code ever again. I would never claim JPA is perfect, but it's better than hand-writing SQL all the time to do trivial things.

We combine JPA 2.0, Hibernate Core, Hibernate Search and Hibernate Validator via our in-house wrapper framework. It does everything we throw at it :)
Combine that with Maven and we have a database built for us too! Add DBUnit into the mix and you've got everything you need.
Wickedly fast searches via Lucene, but using Hibernate Criteria/HQL queries are very cool. All this power behind a GWT suggest box is great.

My advice would be simply to use Hibernate. Hibernate coupled with JPA annotations + Hibernate annotations is pretty powerful. You can even configure an EntityManagerFactory to autodiscover Entities on the classpath but then call getSessionFactory() to leverage the native Hibernate APIs in your application. If you are using Spring it's very easy to do this with LocalContainerEntityManagerFactoryBean and HibernateJpaVendorAdapter.

Sure any ORM is better than hand-writting SQL for CRUD operations... the thing is: I'm think there is no reason to use JPA instead pure Hibernate because I'm mixing both a lot. If I'm not getting a hidden provider why use JPA anyway?

One of the nice things about using JPA vs Hibernate Annotations is the automatic configuration and discovery of persistent classes. Also, it depends on how much of the time you need to break from using the JPA API, if you are only doing it 10% of the time, it would still make switching providers a lot easier than if you were to use hibernate for 100% of your queries.

Related

What's the difference between Hibernate and Spring Data JPA

What are the main differences between Hibernate and Spring Data JPA?
When should we not use Hibernate or Spring Data JPA?
Also, when may Spring JDBC template perform better than Hibernate and Spring Data JPA?
Hibernate is a JPA implementation, while Spring Data JPA is a JPA data access abstraction. Spring Data JPA cannot work without a JPA provider.
Spring Data offers a solution to the DDD Repository pattern or the legacy GenericDao custom implementations. It can also generate JPA queries on your behalf through method name conventions.
With Spring Data, you may use Hibernate, EclipseLink, or any other JPA provider. A very interesting benefit of using Spring or Java EE is that you can control transaction boundaries declaratively using the #Transactional annotation.
Spring JDBC is much more lightweight, and it's intended for native querying, and if you only intend to use JDBC alone, then you are better off using Spring JDBC to deal with the JDBC verbosity.
Therefore, Hibernate and Spring Data are complementary rather than competitors.
There are 3 different things we are using here :
JPA : Java persistence api which provide specification for persisting, reading, managing data from your java object to relations in database.
Hibernate: There are various provider which implement jpa. Hibernate is one of them. So we have other provider as well. But if using jpa with spring it allows you to switch to different providers in future.
Spring Data JPA : This is another layer on top of jpa which spring provide to make your life easy.
So lets understand how spring data jpa and spring + hibernate works-
Spring Data JPA:
Let's say you are using spring + hibernate for your application. Now you need to have dao interface and implementation where you will be writing crud operation using SessionFactory of hibernate. Let say you are writing dao class for Employee class, tomorrow in your application you might need to write similiar crud operation for any other entity. So there is lot of boilerplate code we can see here.
Now Spring data jpa allow us to define dao interfaces by extending its repositories(crudrepository, jparepository) so it provide you dao implementation at runtime. You don't need to write dao implementation anymore.Thats how spring data jpa makes your life easy.
I disagree SpringJPA makes live easy. Yes, it provides some classes and you can make some simple DAO fast, but in fact, it's all you can do.
If you want to do something more than findById() or save, you must go through hell:
no EntityManager access in org.springframework.data.repository classes (this is basic JPA class!)
own transaction management (hibernate transactions disallowed)
huge problems with more than one datasources configuration
no datasource pooling (HikariCP must be in use as third party library)
Why own transaction management is an disadvantage? Since Java 1.8 allows default methods into interfaces, Spring annotation based transactions, simple doesn't work.
Unfortunately, SpringJPA is based on reflections, and sometimes you need to point a method name or entity package into annotations (!). That's why any refactoring makes big crash.
Sadly, #Transactional works for primary DS only :( So, if you have more than one DataSources, remember - transactions works just for primary one :)
What are the main differences between Hibernate and Spring Data JPA?
Hibernate is JPA compatibile, SpringJPA Spring compatibile. Your HibernateJPA DAO can be used with JavaEE or Hibernate Standalone, when SpringJPA can be used within Spring - SpringBoot for example
When should we not use Hibernate or Spring Data JPA? Also, when may Spring JDBC template perform better than Hibernate / Spring Data JPA?
Use Spring JDBC only when you need to use much Joins or when you need to use Spring having multiple datasource connections. Generally, avoid JPA for Joins.
But my general advice, use fresh solution—Daobab (http://www.daobab.io).
Daobab is my Java and any JPA engine integrator, and I believe it will help much in your tasks :)
Spring Data is a convenience library on top of JPA that abstracts away many things and brings Spring magic (like it or not) to the persistence store access. It is primarily used for working with relational databases. In short, it allows you to declare interfaces that have methods like findByNameOrderByAge(String name); that will be parsed in runtime and converted into appropriate JPA queries.
Its placement atop of JPA makes its use tempting for:
Rookie developers who don't know SQL or know it badly. This is a
recipe for disaster but they can get away with it if the project is trivial.
Experienced engineers who know what they do and want to spindle up things
fast. This might be a viable strategy (but read further).
From my experience with Spring Data, its magic is too much (this is applicable to Spring in general). I started to use it heavily in one project and eventually hit several corner cases where I couldn't get the library out of my way and ended up with ugly workarounds. Later I read other users' complaints and realized that these issues are typical for Spring Data. For example, check this issue that led to hours of investigation/swearing:
public TourAccommodationRate createTourAccommodationRate(
#RequestBody TourAccommodationRate tourAccommodationRate
) {
if (tourAccommodationRate.getId() != null) {
throw new BadRequestException("id MUST NOT be specified in a body during entry creation");
}
// This is an ugly hack required for the Room slim model to work. The problem stems from the fact that
// when we send a child entity having the many-to-many (M:N) relation to the containing entity, its
// information is not fetched. As a result, we get NPEs when trying to access all but its Id in the
// code creating the corresponding slim model. By detaching the entity from the persistence context we
// force the ORM to re-fetch it from the database instead of taking it from the cache
tourAccommodationRateRepository.save(tourAccommodationRate);
entityManager.detach(tourAccommodationRate);
return tourAccommodationRateRepository.findOne(tourAccommodationRate.getId());
}
I ended up going lower level and started using JDBI - a nice library with just enough "magic" to save you from the boilerplate. With it, you have complete control over SQL queries and almost never have to fight the library.
If you prefer simplicity and more control on SQL queries then I would suggest going with Spring Data/ Spring JDBC.
Its good amount of learning curve in JPA and sometimes difficult to debug issues.
On the other hand, while you have full control over SQL, it becomes much easier to optimize query and improve performance. You can easily share your SQL with DBA or someone who has a better understanding of Database.
Hibernate is implementation of "JPA" which is a specification for Java objects in Database.
I would recommend to use w.r.t JPA as you can switch between different ORMS.
When you use JDBC then you need to use SQL Queries, so if you are proficient in SQL then go for JDBC.

Hibernate implementation of JPA

I'm wanting using JPA in ear project. Development project must be started ASAP so I have not a lot of time to research and investigate. Could you say please JPA API is restricted functionality of Hibernate or no. At this moment I'm using Hibernate directly. For example in future I'm planing to use hibernate-search and maybe hibernare-validate and -shard. Can I be sure that in future I will not have problem with using this.
And one more example - can I use HAR archive and JPA together.
Why JPA? For project will available RESTful service (jersey or resteassy implementation). And as I looked in much case using JPA for this. I'm a newbie in this so it's only my IMHO. May be i mistakes.
Thanks a lot.
Best regards
Artem
JPA is a subset of hibernate, but you're not limited to it. If you need a hibernate specific feature, you can generally use it at the cost of being tied to hibernate. For example, we've mixed in hibernate annotations with JPA ones, including the validater ones, without trouble.
JPA in theory lets you change the persistance provider later.
Sticking to only JPA compatible configuration can cause more trouble that is solved by the dubious promise of seamlessly swapping providers however.

Is Hibernate deprecated?

This morning I was aboard a S-Bahn (German Subway) and I met a fellow student, who works for IBM. What he is doing there is Java EE optimization. I told him about my little project. And he recommended not to use 'oldschool' Hibernate. That's why my question is:
Is Hibernate deprecated?
(In combination with Java EE/Web Development)
..or did he just prate..
No, Hibernate is not deprecated.
However, there's now JPA (Java Persistence API), which is a standard API for doing the things that Hibernate does.
Note that JPA is just an interface specification. You'll need something that implements JPA, and Hibernate is one of the implementations of JPA. Besides Hibernate, there are a few others such as EclipseLink (the official reference implementation for JPA) and Apache OpenJPA.
Hibernate, apart from being an implementation of JPA, does provide a lot of extra advanced feature that JPA lacks of (extra syntax in query, QBC support etc). Some of them are really useful and hard to find a workaround in JPA world (yet). Without providing such features, it is hard to say JPA can "replace" Hibernate (hence, saying Hibernate being deprecating)
Hibernate is the JPA provider offered by JBoss, which is a Java EE server, so I doubt that Hibernate as an implementation is deprecated.
Perhaps he meant that using Hibernate within a Java EE server , bypassing the container-provider persistence, is deprecated and you should rely on our container for such services.
No, there is no way that Hibernate is deprecated. There is the JPA which is a persistence specification and Hibernate implements it. Also Hibernate has its own advanced features that JPA does not have and that's why Hibernate is the main source of new features that are added to the JPA standard.
One possible reason why he may have suggested you against Hibernate is that for a small project, the overhead of understanding Hibernate can be quite significant.
Hibernate is vast to say the least. Though it can be used in a simple way, but to find that out too, you'll need to comprehend a whole lot more.
but be rest assured that Hibernate is NOT deprecated, or going to be any time in the distant future. it's just that if your ORM needs are modest, you might want to try other solutions like iBATIS
JPA is only one way to do it. There's still Spring and all the other frameworks where Hibernate is well alive.
Based on what you said, it sounds like he may have been referring to Hibernate xml mappings, in contrast to using Hibernate annotations or JPA. XML is most certainly old-school rubbish.

EJB vs Hibernate

When is better to use Hibernate and when EJB 3? Aren't there any impediments with either Hibernate or EJB 3?
I'm in the direct hibernate camp here.
Just think how likely it is that your going to what to change your database say from DB2 to oracle, well that is about as likely as changing from Hibernate to Toplink or eclipse it just isn't going happen that often. It's the same old thing that programmers just love to do and that is abstract any stuff so that they can in at some unforeseen point 10 years from now choose to use a different logging tool kit or what not.
There are I'm sure people out there that really want the vendor independence of JPA but I'm not one of them. That's not to say that Toplink or eclipse aren't any good, I just don't think you can use a product that complex and not be tied (even unintentionally) to it in some way.
Having said that I still follow the hibernate documentation advice and use the JPA annotations and only resort to the hibernate specific ones when I need to, not quite sure if there is a technical reason for this, but it doesn't hurt.
Since Hibernate can be used as an implementation for JPA, you can use it and still be using EJB3. As such, I agree with gid and suggest that you use the JPA stuff in Hibernate until you can't and only then move to Hibernate specific bits.

JPA or Hibernate for Java Persistence?

I'm researching the development of Enterprise Applications in Java, .NET and Groovy. For each platform, we're going to try how hard it is to realize a simple SOAP web service. We'll use the tools and libraries that are most commonly used, to research the real world as accurately as possible.
In this regard, when using Hibernate for persistence, would it better reflect the real world to use the new JPA (Java Persistence API), or the Hibernate custom API that existed before JPA came around?
As you're probably already aware, as of 3.2 Hibernate is JPA certified. You can easily use Hibernate as your JPA provider without having to use any of Hibernate's "custom" APIs.
I'd recommend using straight JPA with Hibernate as the provider. And use annotations rather than XML (much nicer).
Then when you need a little something extra you can always get the Hibernate Session. For example I often find I need to do this in order to pass a collection to a query as a parameter (setParameterList).
It's funny how you worded your question
new JPA ... or plain old Hibernate
Sounds like one has been around forever and the other has just been released. Of course it's not true. JPA was influenced not just by Hibernate but also by TopLink and by J2EE entity beans. The first reference to JSR 220 draft is back from 2003 - how is that for new?
If you use JPA with Hibernate you still use Hibernate and is free to apply any proprietary extensions Hibernate has.
So the choice is yours: use proprietary API or use equivalent established and standard API...
You could stick with a pure JPA spec, just in case you want to swap out Hibernate, but what you'll probably find at some point is that you're never going to swap it out, and you've been missing out on all the really great Hibernate-specific features.
I'd recommend using Hibernate directly, and as Damo suggests, annotations instead of XML. Make sure you have a firm understanding of the "magic" that Hibernate brings. If you're not careful, you could really thrash the database. For example, there's an n+1 query problem depending on how you do #OneToOne joins:
Hibernate OneToOne automatic join fetching (resolving n+1 problem)
I'd also recommend to use an embedded database for unit/integration tests on your Hibernate queries, and watch the SQL that's generated to make sure it looks like something you'd write by hand.

Categories

Resources