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.