I'm writing a JavaFX Application which previously use Spring/QueryDSL for DI and persistence.
I'm hoping to move to using either Dagger or Guice (instead of spring) and Hibernate ORM.
I have noticed that Spring offers some nice functionality on top of hibernate, such as transaction management via #Transactional.
Are there other means of avoiding "boilerplate code" such as opening sessions, beginning transactions, committing transactions and closing sessions via some sort of hibernate configuration? Or are these features I'm really only going to get if I use Spring?
Guice has #Transactional support for JPA providers such as Hibernate using guice-persist, Dagger does not mention support for this.
If you are using Hibernate as your JPA provider, using Spring with #Transactional would probably be the most natural fit for building your backend. You would find a loss less documentation, examples, blog posts, books and online help in general using other alternatives than with Spring/Hibernate.
Related
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.
Considering replacing Spring with CDI in new project, I've encountered a problemchallenge:
We do a plenty of things with SQL queries (for which JPA isn't reasonable): invoking stored procedures, reporting, specialized queries with complicated syntax.
There's a plenty of trivial examples for CDI database access in Internet, and for trivial examples JPA is sufficient. But how do you work with SQL in JPA?
I'm looking for something like Spring-JDBC, with simplified interface for running SQL queries through JDBC and container managing transactions (through annotations), but I havent't found anything yet.
How do one work with SQL queries in CDI? Is it possible with CDI core or extensions?
There isn't anything in the Spec about doing this. You'd have to create your own library, create the transaction layer (or use JTA 1.2 from Java EE 7, or Apache Deltaspike) and build it all up that way. I did mention DeltaSpike, which in the (hopefully) soon to be released version 0.5 will have some of these query and other DB specific features.
CDI stands for Contexts/Dependency Injection (if I'm not mistaken). By itself it has nothing to do with SQL. Using CDI with JPA allows you to work with the database, but even in this case JPA does all the work. CDI has very little to do with it.
If you want to work with native queries and JPA's nativeQuery isn't enough, you'll have to either add the Spring-JDBC dependency to your project, or since you're moving away from Spring, another smaller library that would give you things similar to JdbcTemplate and such.
So to sum it up, CDI has no equivalent of Spring-JDBC, just as Spring doesn't have an equivalent of Swing GUI.
I have been following this tutorial on the Springsource website in order to have basic knowledge of Spring. Everything went good.
Now, I would like to integrate Hibernate to this little application I wrote following this tutorial. I found documentation on different websites (including hibernate's website) but I still have a few questions before starting.
I read some stuff about JPA and I can use it as an abstraction layer on top of hibernate but I don't really understand what for.
In addition, I read somewhere that there is two ways to use hibernate, the first one is annotations and the second one is using javax.persistance, I am right?
Is there some recent documentation about how to use hibernate in an existing spring web application, as well as the different ways to implement it?
JPA is a specification, hibernate can be considered as a implementation of the JPA spec.
You can use either annotation for mapping file with hibernate.
The following tutorials are better:
Hibernate Tutorial Vaannila
Hibernate Tutorial Mkyong
JPA is a standard, Hibernate is an implementation, but has other/additional functionality.
The Spring Reference manual's section on ORM integration covers Hibernate. There are also scores of tutorials and demos, like here, but there are a bunch of other ones, and more recent ones.
I have a few Hibernate Envers listeners which I use for audit purposes. I am just getting started on CDI and so far am pleasantly surprised by its simplicity and power. Since it seems everything is integrating CDI functionality, I thought I'd raise the question, is Hibernate supporting it or will it?
Not only would it be nice to have access to various components, but it would also be great to have access to other contextual information easily and not be limited by Hibernate's interfaces.
The question should be the other way around - will CDI support hibernate integration.
What CDI has to support, probably via an extension, is:
injecting an EntityManager where there is #PersistenceContext, and EntityManagerFactory where there is #PersistenceUnit
transaction and session lifecycle handling
Google for "Weld Persistence Context" and you'll get some examples of how to use Hibernate (JPA) with Weld, which is the reference implementation of CDI. Read this thread as well. And this example
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.