Why use JPA instead of writing the SQL query using JDBC?
Although this is an old question, I feel like it deserves a new answer. I'm a late adopter of JPA, I've been using it on and off for a couple of years, and while I've had my moments of being impressed by the simplicity of standing up a new application, I have become decidedly unimpressed with the performance, complexity and learning curve required to do JPA correctly. The answers in this thread actually reinforce my position.
Firstly, @vineet suggests "the entities can have multiple purposes"... which I've seen in production and I'd say is encouraged by ORM. So much for cohesion and the single responsibility principal. In my experience, adding behaviours to database entities is asking for trouble. I know this because I've done it, and lived to regret it.
Second, there are simple alternatives to the complexity of JPA that provide the ability to use classes with a RDBMS without all the heaviness (and performance issues) caused by the mismatch that ORM tries (unsuccessfully) to solve. We've been using non-JPA relational-class mapping tools for a decade in an application with over 1,000 tables and we simply do not see how JPA is an improvement over more direct access to the database. JPA obscures the power of the database while adding overhead (in the form of annotations and JQL) to the class model... shouldn't it work the other way?
@water suggests numerous things which are true in theory but impractical in reality. For example, having switched backend databases three times I can assure readers that there is no such thing as a few config tweaks and you're done. I'd suggest, if you're spending a lot of time maintaining your persistence layer, your database model is evolving, and you'd be doing the same or more work in JPA. Particularly when non trivial queries in JPA require the use of JQL!
Almost everyone pretends that JPA developers don't need to know SQL. What I've seen in practice is that now we have to learn SQL and JQL. Apparently we don't have to do DDL - but in any non trivial application of course you need to know DDL. Hibernate doesn't even recommend using automatic DDL generation. Apparently we don't have to do DML, except when we call out to a Native Query, which of course is non-portable, smashes the cache, and has all the same problems as JDBC...
Ultimately, in a properly structured application where the domain model is independent from the business logic, JPA provides little in the way of functionality for what I've found to be a very high learning curve - because the domain model is actually very easy to build. I wouldn't use JDBC directly, but something like Apache DBUtils provides a simple layer above JDBC that maps rows to objects, and with a bit of effort can provide most of the advantages of JPA with none of the hiding and none of the overhead.
I've been developing Java database applications since JDBC 1.0, using a variety of libraries (and iODBC and ESQL before JDBC), and for performance reasons alone, I'm done with JPA. But even if performance was better, the learning curve and incomplete abstractions give me serious pause. JPA is complex and tries to hide details which, in my opinion, developers actually need to care about. As an example, we recently saw hibernate issue 250 delete commands to the database when one would suffice. JPA, by its nature, makes this kind of error easy.
I'm not advocating for JDBC, I'm simply advocating against JPA. Developers who don't or can't work in SQL probably shouldn't be writing relational applications - any more than Developers like me, who couldn't do matrix algebra to save my life, should be writing 3D games. Developers who do use SQL for a living should be horrified by the contorted SQL that hibernate, for one, sends to the server, in order to avoid round trips that shouldn't be necessary in the first place.
Why use JPA instead of directly writing SQL query on Java File (i.e. directly to JDBC) ?
Certain projects require engineers to focus more on the object model rather than on the actual SQL queries used to access data stores. The question can actually be interpreted as
Why should one use an ORM framework ?
which can have different answers in different contexts.
Most projects can benefit from having a domain model, with persistence being a second concern. With JPA (implementations) or most other ORM frameworks, it is possible to have all entities i.e. tables in your database, modelled as classes in Java. Additionally, it also possible to embed behavior into these classes and therefore achieve a behaviorally rich domain model. The entities in this model can have multiple purposes, including the purpose of replacing DTOs for transporting data across tiers.
That said, there are places where ORM frameworks may not be a direct fit to the problem, especially when the data model is already established, or when one is working with legacy systems where mapping database tables to Java classes is a non-trivial exercise. And in certain cases, if one needs to absolutely tune the heck out of the SQL generated by the ORM framework, then ORM frameworks are usually a bad fit.
Related Questions
- Java EE Architecture - Are DAO's still recommended when using an ORM like JPA 2?
- Using an ORM or plain SQL?
- ORM vs Handcoded Data Access Layer
What really benefit JPA gives over writing pure SQL in my file?
Here are some of the benefits:
JPA allows you to avoid writing DDL in a database specific dialect of SQL. Instead you write "mappings" in XML, or using Java annotations.
JPA allows you to avoid writing DML in the database specific dialect of SQL.
JPA allows you to load and save Java objects and graphs without any DML language at all.
When you do need to perform queries JPQL allows you to express the queries in terms of the Java entities rather than the (native) SQL tables and columns.
Generally speaking, JPA is simpler, cleaner and less labour intensive than JDBC + SQL + hand-written mappings. The more complicated your data model, the more beneficial it is.
However, if performance is an overriding concern, JPA does tend to get in the way by adding layers between your application and the database. If your application requires you to extensively hand-optimize the native database queries and schemas to maximize performance, JPA is probably not a good fit.
JPA is probably also not for you if you are much more comfortable juggling Java, JDBC and SQL in the same application, than with letting the ORM deal with the messy details. (But if you are, you are probably in the minority ...)