More than 10 years of experience in Enterprise Applications development, and Project Management (since June 2001). Specialties: Enterprise Applications, J2EE, J2SE, Spring Framework, Spring Security, Spring Webflow, JPA and JDBC, JMX, JAXB, JUnit; XML, XSLT and XSL-FO; HTML/CSS, Javascript, JSON, jQuery/jQuery UI; RDBMS (Oracle, SQL Server, MySQL), PL/SQL; UML; Mobile Applications, mostly in Objective-C targeted iPhone/iPad Michal is a DZone MVB and is not an employee of DZone and has posted 12 posts at DZone. You can read more from them at their website. View Full User Profile

JPA - Should I Become a Laziness Extremist?

05.01.2013
| 2542 views |
  • submit to reddit

When you speak with the Developers about mapping objects to relational databases, they very often complain about poor JPA performance, unpredictable behavior of JPA Providers, etc. Usually at some point of the conversation you will hear: "Let's drop this technology at all, we've seen something much better on the conference last month. We will use it in our projects instead of JPA and develop them happily ever after." - Sounds familiar? :)

It's nothing wrong in learning new technologies, in fact you should do it constantly, to improve your skills and knowledge, but when you have problems with one of them, will you choose an easy path to another technology, or ask yourself: "Am I using it in a right way?"

Let's look at the JPA usage example. Suppose that we have simple database, mapped to the entities:


and we have to display all employee names, regardless their employer (and department). Nothing easier ;) - simple JPQL query will do that:
select employee from Employee employee order by employee.name Many developers finish at this point, and celebrate with Friends another successful JPQL query in their life ;), but some of us have this strange feeling, that something creepy is lurking beneath the shiny surface. SQL queries produced by the JPA provider (ex. Hibernate) will reveal the truth:
select [...]  from EMPLOYEE employee0_ order by employee0_.EMPLOYEE_NAME
Nothing special, so far :), but here comes the naked truth:
select [...] from DEPARTMENT department0_ left outer join EMPLOYER employer1_ on department0_.EMPLOYER_ID=employer1_.EMPLOYER_ID where department0_.DEPARTMENT_ID=? select [...] from EMPLOYER employer0_ where employer0_.EMPLOYER_ID=? select [...] from DEPARTMENT department0_ left outer join EMPLOYER employer1_ on department0_.EMPLOYER_ID=employer1_.EMPLOYER_ID where department0_.DEPARTMENT_ID=? select [...] from DEPARTMENT department0_ left outer join EMPLOYER employer1_ on department0_.EMPLOYER_ID=employer1_.EMPLOYER_ID where department0_.DEPARTMENT_ID=? select [...] from DEPARTMENT department0_ left outer join EMPLOYER employer1_ on department0_.EMPLOYER_ID=employer1_.EMPLOYER_ID where department0_.DEPARTMENT_ID=?
What the heck?! What are these queries for?! - Well the reason lies in default fetch attribute values for @ManyToOne annotations, which is EAGER. My database holds 2 Employers, one of them has 4 Departments, while second one hasn't any. When the Employee is loaded, JPA provider loads by default all EAGER associations (in our case both Department, and Employer), thus we have the additional queries. As you see above the JPA provider is clever enough to load both Employer and Department at once, when it is possible.

You've just found magical JPQL query fetching all the database content at once :). Does this situation remind you something in the past? ;)

What can we do about it? - My Friend, all you need is a laziness :) - Don't use EAGER unless it is REALLY needed (and remember that @ManyToOne and @OneToOne annotations use it by default).

You may call me a lunatic, or laziness extremist at this point :) and ask: Have you ever encountered LazyInitializationException, Bro!? Have you heard of all the mess with lazy loading problems!? Performance degradation, etc. ... Of course I did :), but don't you think that if we are getting in such troubles with JPA, maybe we use it in a wrong way?!

What we do usually in Web Applications is presenting or editing some data on UI, and usually it is only small subset of specific entities' properties. Doing it requires fetching the entities tree from the database - without batting an eye, we ask Entity Manager: give me all Employees, sorted by name, with all related entities, and then complain on degraded performance!

We don't care what we fetch from the database, because Entity Manager will do the donkey work for us. We get LazyInitializationException, so what! We will use Open Entity Manager in View pattern, and silence this stupid exception!

Give a me a break! Don't you think it's a dead end? :) - It's about time to change something :) There are sophisticated methods which you can use in your projects, like CQRS for example, along with possibilities already existing in JPA, which can help you change the bad manners described by me in this post.

To be continued ...

Few links for the dessert:

 

Published at DZone with permission of Michal Jastak, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Thomas Courant replied on Mon, 2013/05/13 - 9:26am

i don't understand well your article, cause i don't know if you are ironic about JPA.

But i take the opportunity to tell that my experience with a large application using JPA is not a good one. Poor performance and maintenability, required large knowledge of JPA, bugs in implementation (EclipseLink bugs not fixed on windows platform !!), poor exception information...

it took 3 years to do the application, so i take the time to develop with JPA, and i am very deceived.

Michal Jastak replied on Sun, 2013/05/19 - 3:59am in response to: Thomas Courant

 Thomas,

my article is rather a statement of developer:

  • who knows that's very easy to misuse JPA, which among others, may lead to very poor performance of application
  • who thinks that JPA is very often misused, because we as developers, very often choose the easiest way instead the right one, or what is even more worrying, we don't know how it should be used right, and don't care about it :(
  • who knows that JPA providers are buggy, at least all known to me ;), and what is worse, some people standing behind the provider code have not enough courage to say something else than "It's not a bug, it's a feature" ;)
  • who dreams about the persistence API, which is simple, powerful, and difficult to misuse, because of its design ;)

regards :)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.