TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Problems with JPA/Hibernate

96 pointsby stemlaurabout 4 years ago

26 comments

doctor_evalabout 4 years ago
In my extensive experience managing teams using JPA ORMs including Hibernate and EclipseLink, you not only get to learn the unavoidable details of your target database’s SQL, but also the complex, non-obvious side effects - especially caching interactions and performance edge cases - of the ORM as well. You also get to learn two distinct but similar query languages (one of which you can’t use anywhere else but Java). You get to throw away all the semantics built into the database structure, including knowledge about indexes, and you need to duplicate almost everything from SQL into Java, in the form of complex annotations against entity objects that you often wouldn’t need with traditional SQL access patterns. And when something goes wrong, you have a large, complex framework, including an inscrutable caching layer, between your code and your data - which can make debugging JPA code very challenging.<p>In return you get reduced performance, overly complex and difficult to read SQL code generation, an inflexible entity model, and non optimal database access patterns.<p>JPA is an extremely complex framework whose benefits, in my opinion, outweigh the costs in only a small number of relatively simple use cases. And even in those simple use cases, in my experience it is far less performant (and double the LOC) than using SQL directly.<p>I’m not saying you can’t use JPA in large, complex applications, because you obviously can. But those applications are harder to write, much larger, less maintainable and less performant than the equivalent applications written with simpler frameworks or libraries.<p>I personally found MyBatis annotated interfaces to be the ideal way to map SQL to Java, but perhaps ApacheDB is better for smaller projects.<p>JPA is one of those fabulous engineering experiments that, sadly, didn’t work out. It breaks every rule in the engineering book in order to make SQL work like Java, but it doesn’t succeed, and I could never recommend it to anyone.
评论 #26775056 未加载
评论 #26774904 未加载
评论 #26775148 未加载
评论 #26776485 未加载
评论 #26777204 未加载
评论 #26776284 未加载
评论 #26777010 未加载
dale_glassabout 4 years ago
I disagree with this bit:<p><pre><code> A User can be considered unique in one context by its email address, or by its social security number </code></pre> Personally, I&#x27;m a fan of giving everything a random UUID, because it&#x27;s more flexible. It&#x27;s random and impossible to guess, it scales well because there&#x27;s no central bottleneck like with an autoincrement, and it&#x27;s future proof and flexible.<p>What happens when the user changes the email address? What if the social security number changes, because it was wrong or because it actually changes? What if the original unique identifier wasn&#x27;t a good choice? What if we decide that the user can have multiple email addresses? Then you may end up having to restructure the entire database, which will be a very annoying thing to do. What if you implement additional rules for what an email is allowed to look like and now the constraint fails for existing users, and this correction needs to be propagated to millions of already existing rows?<p>Real-life personal data is weird and fuzzy. They can violate seemingly sensible rules like being unique, unchanging, or conforming to any rule whatsoever. Best not to let them spread all over the DB and cause trouble later.<p>Instead, you could just have a random ID that doesn&#x27;t mean anything and therefore can stay fixed forever, and any user-related metadata stays in the user table, where it can be modified as needed. Plus an UUID is a fixed 16 bytes, which is easy and efficient to deal with.
评论 #26773786 未加载
评论 #26776824 未加载
评论 #26773909 未加载
评论 #26773821 未加载
评论 #26777155 未加载
the_afabout 4 years ago
The underlying problem is one of O-R impedance mismatch. Going full SQL and getting rid of the ORM is a possible answer, but it has tradeoffs and is not a silver bullet. It might mean re-creating from scratch an in-house, bug-ridden ORM, or ditching OOP idioms from your language, or both.<p>The author of TFA seems to be going through one of the stages described in &quot;ORM is the Vietnam of Computer Science&quot;, an article that should be mandatory reading before one claims to know the solution to this decades old problem.
评论 #26775087 未加载
评论 #26773479 未加载
评论 #26776124 未加载
评论 #26780331 未加载
kleinschabout 4 years ago
Everyone hates JPA&#x2F;Hibernate, but what’s the alternative? I’ve seen this a few times. “You don’t need an ORM, write your own SQL queries directly and create a beautiful domain driven design object model” leads straight into a project only the owner will understand. Homegrown mini-ORM that’s full of pitfalls, inconsistent object model, hacks and TODOs all over the place.<p>If you’re living in the Java ecosystem, the biggest benefit is that you have a massive library ecosystem and developer base that understands it. If you’re going to throw all that out and require new people to learn your homegrown mess, why not pick a language that’s more interesting than Java? Then you’ll get new developers that are anxious about Go&#x2F;Elixir&#x2F;WhateverHotness.<p>Saying this as someone with 15 years in Java world.
评论 #26776721 未加载
评论 #26774979 未加载
评论 #26776400 未加载
评论 #26778154 未加载
评论 #26777075 未加载
评论 #26775301 未加载
评论 #26774803 未加载
评论 #26776185 未加载
评论 #26777435 未加载
vips7Labout 4 years ago
This article is... Questionable at best. I don&#x27;t think any of this is an argument against JPA, except that the author doesn&#x27;t like how it works? I also suspect the author doesn&#x27;t know hibernate that well.<p>For instance selecting just the fields you need is relatively simple with JPQL:<p><pre><code> SELECT i.url FROM Image i WHERE i.id = ...</code></pre>
评论 #26773912 未加载
评论 #26774014 未加载
评论 #26773712 未加载
jacques_chesterabout 4 years ago
I largely agree that JPA is a maddening mess[0]. However, this sentence caught my eye:<p>&gt; <i>I love open source, really, but big companies sponsoring open-source projects get most of their income from support or third party tools.</i><p>I work for VMware and consequently take some interest as to how my salary comes into being.<p>If you think VMware makes &quot;most of its income&quot; from supporting Spring, then I think I&#x27;d encourage you to spend some time at the investor relations site[0] reading any of the annual or quarterly reports. I&#x27;d advise the same for Oracle and Red Hat&#x2F;IBM.<p>[0] The advice to use emails or SSNs as primary keys, though: yikes.<p>[1] <a href="https:&#x2F;&#x2F;ir.vmware.com&#x2F;" rel="nofollow">https:&#x2F;&#x2F;ir.vmware.com&#x2F;</a>
评论 #26775197 未加载
ChrisWreckabout 4 years ago
Going from using only JPA&#x2F;Hibernate for everything, to use a combination of both jOOQ and JPA&#x2F;Hibernate on a project, is probably the best decision I&#x27;ve made. Using each tool at what I believe they do best.<p>I use JPA&#x2F;Hibernate for most writing and inserts. It helps a lot when you&#x27;re dealing with aggregates with child and child entities. It would be a nightmare to track all changes myself and try do manually do what the ORM is doing for me. Deleted a child of a child of an aggregate? No problem, persist only that.<p>I&#x27;ve started to separate my JPA&#x2F;Hibernate entities from my domain models as well, and it looks promising. There&#x27;s some more mappins, but my domain won&#x27;t be polluted with database concerns.<p>Then I use jOOQ for almost all reading of data, reading into custom read models that fit the view they are supposed to be shown in. No problem doing multiple joins or other stuff that would give you an immediate headache when trying to solve using JPA&#x2F;Hibernate.
exabrialabout 4 years ago
I don&#x27;t want to sound like I particularly love the orm pattern when I say this... But his information is about 10 years out of date. Many of the claims simply aren&#x27;t true anymore or the world has moved past by other means. For instance one of his very specific claims, getters setters must be present, definitely is not true for current versions of every JPA implementation. In the claim about a default noop constructor, you can&#x27;t possibly be serious unless you are doing true oop and in that case you are awarded no points and may god have mercy on your soul.<p>The beauty of dependency injection is it did more to make Java a functional language than Java8 with lambda notations. That pretty much eliminates the need for pure OOP, which JPA attempts to imitate. In reality JPA + JTA is a pretty awesome combination and avoids the stupid OOP paradigm.<p>Again. Argh. I would write a response blogpost, but argh, apathy for the orm pattern.
lmmabout 4 years ago
This is a common criticism but still extremely shallow. JPA&#x2F;Hibernate is still the best way to actually produce working applications if you have to use an SQL database for some reason. To go point by point:<p>Mutable datastructures with default constructors and setters: yes, mutable entities suck. Unfortunately SQL is fundamentally built around mutable entities. Every field of your POJO is writable because every column of your database is writable. The impedance mismatch is big enough already without trying to make objects that behave differently from your database. Yes, an object shouldn&#x27;t just be a datastructure with methods; unfortunately an SQL table row is just a datastructure, and classes are the only mechanism Java offers for representing such a thing. Same for mutable collections.<p>Reflection (which is the reason classes must be non-final): again, sucks, again, the only way to do something like this in Java.<p>Lazy loading is wonderful. Put your session in your view, write a normalised set of entities that actually model your domain, and get on with your life. Don&#x27;t worry about the details of what loads when unless and until you have to.<p>Those who don&#x27;t understand Hibernate caching are doomed to reinvent it poorly.<p>Don&#x27;t use your database as an API. Yes, Hibernate&#x2F;JPA needs to own your database. That&#x27;s as it should be. SQL databases are way too complex to be shared between independent applications.<p>Do you really think people who can&#x27;t be bothered to learn and understand Hibernate properly are somehow going to take the time to learn and understand &quot;vanilla SQL&quot;? Why?<p>None of the problems listed here are problems of JPA&#x2F;Hibernate. They&#x27;re problems of SQL databases which are surfaced through JPA&#x2F;Hibernate, but if you skip out on JPA&#x2F;Hibernate you still get exactly the same problems (maybe in a slightly less recognisable form). The real solution is to stop using these overrated datastores, but if you must use them then JPA&#x2F;Hibernate is the least-bad way of doing so.
评论 #26775624 未加载
评论 #26775834 未加载
评论 #26776817 未加载
评论 #26777544 未加载
评论 #26775801 未加载
victor106about 4 years ago
Lot of Hibernate hate in this thread. This really helped me. Strongly suggest. Also Vlad writes really awesome posts on using Hibernate along with Spring etc.,<p><a href="https:&#x2F;&#x2F;vladmihalcea.com&#x2F;courses&#x2F;" rel="nofollow">https:&#x2F;&#x2F;vladmihalcea.com&#x2F;courses&#x2F;</a>
评论 #26782490 未加载
victor106about 4 years ago
Just because you&#x27;re using Hibernate doesn&#x27;t mean you have to use it for everything<p>—Gavin King, creator of Hibernate<p>Source:-<p><a href="https:&#x2F;&#x2F;twitter.com&#x2F;markuswinand&#x2F;status&#x2F;456827165938434048?s=21" rel="nofollow">https:&#x2F;&#x2F;twitter.com&#x2F;markuswinand&#x2F;status&#x2F;456827165938434048?s...</a>
评论 #26775218 未加载
karmakazeabout 4 years ago
Hibernate was made to solve the problem of JavaEE enterprise bean persistence. It made sense 20 years ago. It is a mismatch for the API-oriented transactions we tend to write today.
amenghraabout 4 years ago
I solve Hibernate problems by using jOOQ instead. The migration more than paid off the couple times I did it.
评论 #26777472 未加载
paulryanrogersabout 4 years ago
&gt; This loop has to stop, what defines the value of the projects we are working on has nothing to do with technologies and frameworks.<p>&gt; I WANT to solve business problems, I do not want to keep solving technical issues.<p>It is interesting how emotionally invested we become with our tools. Yet we don&#x27;t have infinite time to become productive with all possible frameworks. So we have to specialize at least somewhat.<p>As to JPA itself, I agree that it&#x27;s generally a bad fit for most uses. Circa 2010 I used it with Java Enterprise in the hope that an failed bean could be recovered by a parallel worker, but the technical costs were crazy high. And often I had to drop to raw SQL anyway. Less invasive ORMs can still be more generally useful, and remove some tedium.
islonabout 4 years ago
This post reminds me of what happened some weeks ago at my job.<p>We use Clojure and yesql (a library where you write sql queries directly in .sql files and the library generates functions for you). The devops noticed one of our queries was slow and taking too much DB resources. He sent us the query which we promptly found and then asked us if we could change it to a more performant version he just wrote.<p>We took his query, just replaced in our sql file and deployed. 10 minutes later he came back saying things look much better and the query update really helped.<p>I wonder how much time it would take if we were using JPA&#x2F;Hibernate as we used to, many years ago.
KamBhaabout 4 years ago
I find this argument a little odd:-<p>&quot;Frameworks do not keep retro-compatibility&quot;<p>I would argue that is a good thing and in the case of Spring, doesn&#x27;t feel true. In part, Spring is so hard to learn because it has too much support for legacy stuff (though this may have changed in the last few years).<p>The only issue with not supporting retro-compatibility is because the JVM doesn&#x27;t support retro compatibility. I recently tried to upgrade an application to the latest version of Java (I think it was Java 12) and found that date formaters were completely changed to match an ISO standard which broke a lot of code. We also found a similar problem with the Java 8 transition as well forcing a huge upgrades to our libraries.<p>I am of the view that libraries and frameworks should support not support retro compatibility but the language should. This way, if you don&#x27;t want to upgrade your library then you don&#x27;t have to.<p>Using the web as an example, old Angular JS applications still work today as they did back when they were first written. I doubt applications written in the first version of Spring will work with the latest version of the JVM.
apiabout 4 years ago
From my experience ORMs are good time savers when you have relatively simple query needs, but fall down when things get really complex.
评论 #26773642 未加载
评论 #26773625 未加载
评论 #26773892 未加载
评论 #26773706 未加载
Uehrekaabout 4 years ago
Sorry for being off-topic, but why is Hibernate called Hibernate?<p>I can&#x27;t find an explanation on the Wikipedia or GitHub pages, and whenever I see the name come up on HN my brain does a weird double-take as it goes &quot;Is this an OS hibernation tool--No, it&#x27;s the Java database thing... does it make objects go to sleep?&quot;
评论 #26776861 未加载
评论 #26775871 未加载
watwutabout 4 years ago
&gt; Nobody understands the cache mechanism, you end up de-activating it. Worse, those understanding it are not caching query responses, they are caching entities.<p>I feel like hiring process should filter these kind of developers out. At least most of them.<p>I also think that if they get in, internal processes should limit these developers impact, limit their ability to make decisions. As in their careers should be stagnant and they should not be gaining influence.
harryvederciabout 4 years ago
The only positive experience I&#x27;ve had with it was in a small application with a not-so-complex DB which was created entirely through Liquibase.<p>In large enterprise projects, I&#x27;ve always had to create custom SQL statements at some point, at which point I&#x27;d rather do everything in SQL. Otherwise, you have to know JPA&#x2F;Hibernate <i>and</i> SQL, which (in my opinion) defeats the purpose.
kgeistabout 4 years ago
Interesting, as far as I know, PHP&#x27;s Doctrine was influenced by Hibernate but it doesn&#x27;t require parameterless constructors, and data is hydrated directly as object fields, without requiring getters&#x2F;setters. What&#x27;s the reason for enforcing such requirements in Hibernate?
评论 #26776767 未加载
xupybdabout 4 years ago
I have been using Entity Framework recently. I&#x27;ve not had any past experience where I have liked an ORM. This one seems alright.<p>I do wonder if I will fall into the same trap as complexity grows. But the migrations are just amazing so far. For them alone I want to stick with it.
jillesvangurpabout 4 years ago
There are lots of valid reasons to avoid JPA&#x2F;Hibernate beyond those listed in the article.<p>- Hibernate is using blocking IO and threaded database pools. This makes it a problem if you want to use non blocking web frameworks. Like Spring&#x27;s web flux. You should consider it a legacy technology for this reason alone. There&#x27;s a good reason why there is no drop in reactive replacement: modern frameworks are trying to not repeat some of the design problems with hibernate (see the article for an overview of those).<p>- It comes with its own category of hard to diagnose and fix bugs. I&#x27;ve been on more than one project where I had to clean up other people&#x27;s messy transactional logic. One symptom is people copy pasting @Transactional everywhere as if it was some kind of magical incantation that says &quot;dear db gods please just make this work consistently&quot;. A second symbol is flaky tests where that clearly is not working as advertised. A lot of this relates to things like aspect oriented programming and reflection which are what hibernate uses to generate byte code at run time.<p>- For the same reason, hibernate is also a problem if you want to natively compile your code via e.g. Graal. Reflection and byte code generation are problematic for that. The less you have of that, the better.<p>- For the same reason, hibernate is also inappropriate if you need fast startup times (which would be why you&#x27;d consider native compilation). For example because you are doing server-less designs or edge computing. Having 10-15 seconds of startup overhead is not great. Warming strategies can mitigate this somewhat. But honestly, there&#x27;s no good reason for Java servers to take much longer to start than it takes the JVM to start (which is still around a second or so). As soon as you get rid of hibernate, Spring Boot startup times become a lot more reasonable. If you then switch to using it&#x27;s bean DSL (as opposed to scanning packages for annotations), it gets better still. Most of what Spring does at startup is millions (literally) of calls into various reflective methods. That&#x27;s why it takes so long.<p>- Object impedance mismatch. Designs that need an ORM layer might not be that optimal. I&#x27;ve been on multiple teams where people got carried away a little too much with e.g. overusing inheritance and coming up with complex solutions to make the database mirror the class hierarchy. The result is dozens of tables and dozens of joins on read. I&#x27;ve seen GET operations that had 1500ms response times because of this. It&#x27;s stupid. It&#x27;s stupid even after you fix all the silly joins, missing database indices, etc. You can do good database design with hibernate of course. If you understand how to do that, hibernate is just another tool and not a particularly critical or important one. I&#x27;ve removed it on a few projects to simplify the design.<p>- These days it is valid to treat databases as document stores. Once you refactor a 15 table database to be the 3 tables that you really needed all along, most of Hibernate is just not needed. My golden rule is that if I don&#x27;t query on it, I don&#x27;t need (or want) separate tables or columns for it. Nothing wrong with storing some json blobs. I love using databases because they are fast, transactional, and come with some strong consistency guarantees. Hibernate is not a great fit for document databases. It assumes your domain consists of columns and tables and it wants to do clever things with joins to make that seem like an object tree. The best join is the one you don&#x27;t need. That&#x27;s why document stores can be so nice.<p>If I had to do a green field project, I&#x27;d probably go for R2DBC with Spring or maybe one of several other Kotlin reactive database frameworks in combination with ktor, http4k or one of the other emerging Kotlin server frameworks. All my recent projects are using spring web flux and Kotlin co-routines in any case. So, using something non blocking is a hard requirement for me.<p>But if I had to use hibernate, using Kotlin is the way to do it. It shovels most of the ugliness under the carpet via compiler plugins. So you can use nice immutable data classes and let the kotlin compiler worry about adding default constructors, opening the class and adding getter and setter cruft just so hibernate can do its runtime magic. Also it removes all of the need for hacky things like Lombok and its gazillions of additional annotations. Hibernate can be a lot less painful if you just do it properly. But not using it is better still.
nnandaabout 4 years ago
JPA madness is still ON and that is unfortunate. Spring framework guys at Pivotal are designing all kinds of database access (SQL, NoSQL) around JPA interfaces.
cryptosabout 4 years ago
A default constructor must be present, yes, but if you use Kotlin a compiler plugin can generate this constructor that is not visible in your code base (but would be if another module would use the compiled byte code).<p>JPA&#x2F;Hibernate does not require getters and setters. Fields can be used directly for ages (more than 10 years).<p>The arguments against reflection are pseudo arguments, because the developer doesn&#x27;t use reflection himself where usual programming language means would be better. Instead the framework uses reflection to free the developer from writing boilerplate code - completely different things!<p>The claim that it would be impossible to return unmodified collections because one would be forced to provider getters and setters is wrong. If Hibernate uses the fields directly, it is no problem to give only an unmodifiable view of a collection to the outside.<p>I don&#x27;t see a general problem with lazy loading. You have to understand what you&#x27;re doing, but that should be the case with every framework. Hibernate is quite flexible with eager and lazy loading and it is possible to specify an entity graph per use case to say Hibernate what to load eagerly and what not. Another possible is to use dedicated query objects (usual entity classes mapped to the same table, but designed for a certain use case).<p>The section about &quot;Accessing a single table field&quot; ignores the fact that the object mapped with Hibernate could also only use the needed fields. You could even select a single value with JPQL without any domain class involved. This argument is kind of dumb and wrong.<p>&quot;Constraints&quot; with Bean Validation are not a core part of Hibernate and shouldn&#x27;t really be in this article. But, as they are already there, let me say that the criticized &quot;too late&quot; enforcement of the specified constraints is only the default behavior (because Hibernate can not know when to perform the check). Nothing prevents you from performing these checks explicitly with the means of the Bean Validation API. But apart from that, I&#x27;d prefer to write this kind of rules as usual code, too.<p>&quot;Framework updates are horrible&quot;: I had never a severe problem switching to a new Hibernate version. Same is true for Spring (but wait, why does this article mention Spring at all?).<p>&quot;Rename your JPA Repositories to JPA DAOs&quot;: The author doesn&#x27;t understand the difference between a DAO and a Repository. A repository is at the same level as an entity or value object, it _is_ a domain concept. BUT the implementation of the repository interface is indeed part of the infrastructure, but this implementation would reside in another package. There is no need to name &quot;repositories&quot; always &quot;repository&quot; - if you want to name the class &quot;BankAccounts&quot; then do so! By the way: the class name &quot;BankAccountsJPAImpl&quot; is a crime!<p>The advice to generate IDs in your own implementation is kind of silly. &quot;if an id is generated, it should be done knowingly&quot; Why? Usually an ID is just a number with no special meaning other than being unique per entity type. Even if you&#x27;d decide to drop relational databases and use advanced CSV files instead the sequence number generation could easily be implemented then. And why on earth should one want to test the sequence number generation? I trust every solid database to be able to generate perfectly fine sequence numbers!<p>The section &quot;Stop adding multi-directional association&quot; has nothing to do with Hibernate specifically, because that is some kind of general design consideration.<p>One big question remains unanswered by this article: What is the alternative? The author implicitly suggests that it would be SQL. But things are not so simple. If you want to have a domain model (and not a mixture of domain logic and technical infrastructure), you not only have to load data from the database and create objects from it (the easy part), but you also need to find out what data needs to be written to the database after business operations were performed. I&#x27;m not aware of a simple solution here (but let me know ...). There are other things like optimistic locking where Hibernate simplifies things a lot.<p>All in all the article is not well balanced and flawed.
Areading314about 4 years ago
What is the argument in favor of server-side Java in 2021? It seems like alternatives like Go, Python, or even JS are far ahead at this point
评论 #26773323 未加载
评论 #26773312 未加载
评论 #26773815 未加载
评论 #26773502 未加载
评论 #26773529 未加载
评论 #26774882 未加载