Preface
Welcome to the second edition of the book about my rather unorthodox approach to object-relational mapping in general and the Java Persistence API (JPA) in particular. It’s also about Querydsl, because since I was recommended this library I completely fell in love with it. It never let me down, it is actually joy to work with it – which is not that common in our programming profession.
This book is, as the title suggests, very opinionated. Sometimes you may ask: “Why the hell this guy still uses JPA?!” It is not a typical tutorial book covering the technology systematically – I cherry-pick instead. It’s not a typical best practices book either. I use ORM technology but not quite as intended. I even left the safe water of the JPA specification – although originally unintentionally because the reference implementation (EclipseLink) let us without warning.
We decided to take control over the SQL statements our system produces. You can’t rely much on lazy or eager fetch types, because often (as the specification says) these are mere hints, not real promises. Even with rather SQL-like approach JPA still provides big benefits over plain JDBC. We tuned down the “mapping” part of the ORM a little bit and our entities resemble “raw” tables more. You may feel like shouting “that’s all wrong!” – which is OK. Let me answer the following question first…
Is this book for you?
This book is for anyone who actively uses JPA – preferably in version 2.2 (Java EE 8) – and is not completely happy with it. It’s main focuses is on painful points related to relationship mapping where benefits mix with unavoidable drawbacks. Even if you’re happy with JPA as it is, the book still can give you more options how to solve your problems.
Some of the considerations are related to ORM in general and may be applicable for non-JPA ORM providers, but I can’t guarantee that. Some parts of the book are more generic and based on common sense (like “avoid N+1 select”), others are strictly JPA related (like how to achieve modularity). Some are probably complete answers, recipes even, others are open topics that only raise further questions.
I’ll use Querydsl throughout the book because that’s how JPA Criteria API should have be. I believe Querydsl still does not have adequate (and deserved) coverage in books.
Not in the book
This is not an introductory book about JPA, see the next section about other JPA related books. I expect you know ORM and JPA at least superficially, you work with it for whatever reason (or will, or want to) and you are interested in something beyond reference material. It does not mean it is a difficult book though, as I always try explain the problem I talk about.
This is not a book about architecture, at least not primarily, although patterns how to use JPA are somewhere in the area. I take kind of “Fowlerish” liberty of mixing design and architecture and blur the line between them. I admit I have not yet worked on such a project where thinking architecturally big would pay off. Instead I have seen architecture on projects where the effort was wasted for various reasons. Some of them are easy to guess if you’re interested in an agile or lean software development. That said, I’ll talk about some design considerations, for instance about the contract between presentation and session layer.
This book does not cover any of these topics:
- JPA support for native SQL – I don’t use it massively and I have nothing much to say about it.
- Calling stored procedures – it works as expected.
- Criteria API – because I prefer Querydsl instead.
- Locking, concurrency, validation, transactions and other features not affected by the opinionated approach.
- High performance – we mention performance, and the advices should not affect it negatively, but I don’t focus on high-performance tricks in particular.
Most of these are covered elsewhere anyway. Let’s talk about other books available in this segment.
Other JPA books
JPA 1.0 came with EJB 3.0 back in 2006, first as a part of JSR 220: Enterprise JavaBeans 3.0. It soon proved as a worthy API on its own because it is not tied to EJB in particular. In those days I’d recommend Pro EJB 3: Java Persistence API, but I think the book is now massively outdated.
I can highly recommend Pro JPA 2 in its 2nd Edition [PJPA2], which is updated to JPA 2.1 (in line with Java EE 7). There is hardly anything I haven’t found in this one. Sure, it’s closing on 500 pages, but it’s structured well. It has minimal overlap with the rest of Java EE in Chapter 3: Enterprise Applications, but even that part may be useful. This is currently my go-to book when I need to refresh some JPA knowledge.
Then there is Spring Data book [SData].
For the sake of confusion there are actually two books of this name – one published by O’Reilly
and the other one by Packt, both published within a month late in 2012.
If you are Spring positive, I can only recommend reading at least first 50 pages of the one by
O’Reilly (up to chapter 4 including), even if you don’t use Spring Data after all.
It’s a nice quick overview of JPA and Querydsl with examples of Spring configuration both in XML
and Java and they even mention things like orphanRemoval (although rather in passing).
It’s definitely a little time well spent.
I don’t know any other relevant books, but there is one more obvious resource – Java Persistence 2.2 Specification itself [JPspec] (or older Java Persistence 2.1 Specification [JPspec21]). There are things you hardly find anywhere else, especially when it comes to corner cases like “use of DISTINCT with COUNT is not supported for arguments of embeddable types or map entry types”. So when you encounter a problem it is good to search through the specification for keywords. Often JPA provider works as specified, even when it does not make sense to us.
There are tons of blog posts, of course, some of them are very influential. I will mention the most important ones in chapter Love and hate for ORM.
Books on performance of the database and persistence layer
Any book about persistence gives at least some elementary advices on performance. You definitely should consult the documentation to your provider. I can also recommend two books on Java performance in general – both named quite plainly: Java Performance (2011) [JP] and Java Performance: The Definitive Guide (2014) [JPDG]. The first one has a final chapter named Java Persistence and Enterprise Java Beans Performance, the second one deals with the topic in its penultimate chapter Database Performance Best Practices. Finally, there is also a very recent book that covers performance of Java persistence specifically – High Performance Java Persistence [HPJP].
Looking back to Patterns of Enterprise Application Architecture
Martin Fowler wrote his Patterns of Enterprise Application Architecture [PoEAA] in 2002 trying to capture various patterns that were reoccurring in enterprise applications, not necessarily written in Java. Many patterns in the book cover data access layer and many of those are clearly ORM related – starting with Data Mapper going through Unit of Work or Lazy Load to many more related to concrete mapping problems.
Reading the material so old also gives you the idea how well the patterns stand the test of time.
In 2002 Java was 7 years old, now it’s over 20.
There were no annotations and dependency injection was known in theory, but there was no wide-spread
container supporting it (mind you, Spring 1.0 was released in 2004).
Years later we still used various SessionHelper static classes to work with Hibernate Session
in thread-local manner, often forgetting to close session because we were not able to clearly put
open and close to a single method with try/finally block.
That was before we read books like Clean Code… probably because they were not yet written.1
Closing his chapter Mapping to Relational Databases Martin Fowler wrote:
Today there are more books related to ORM, even if you narrow it down to Java world. My attempt tries to step away from many ORM concepts and go back to SQL roots to a degree. That does not change the fact that Fowler’s work organizing and describing all these (still applicable) patterns is remarkable.
Structure of the book
In the first part of the book we’ll quickly go through JPA highs and lows (all highly subjective, you know the disclaimer drill) with a bit of historical context as well. This part should prepare a backdrop for any further arguments.
In the second part of the book we will get opinionated. After an introduction for my case we will make a detour to meet Querydsl, because I’m not willing to go on without it. Afterwards we’ll see how to work around the features marked as questionable (where possible).
Third part talks about more common problems you encounter when working with the JPA (like paginating and N+1 select) and offers solutions for them.
Finally, appendices will provide short references for related technologies I used throughout the book (e.g. H2 database, project/build structure) and other additional material.
Using code examples
Book is written on GitHub and all the code is in the GitHub repo for the book.
You may download the whole repository or browse it online, the most important snippets of code
are presented in the book.
Because I present various JPA models and setups examples are split into many small projects,
each with its own Maven pom.xml (or Gradle build in some cases).
Entity classes and other “production” code is in the src/main/java (or resources)
while demo code is in the src/test/java.
If you want to run it in IDE, I recommend those that can create multiple run configurations and
are able to run normal classes (with main) from the test sources as well – I suspect some
prominent IDEs don’t support this.
But you can always run the demo code using Maven from the project directory (e.g.
examples/querydsl-basic) with the command like:
1 mvn test-compile exec:java -Dexec.mainClass="tests.DogQueryDemo"
There is also neat way how to download subtree of a GitHub project using SVN export. This makes running any example on the command line a breeze:
1 svn export \
2 https://github.com/virgo47/opinionatedjpawithquerydsl/trunk/examples/querydsl-basic
3 cd querydsl-basic
4 mvn test-compile exec:java -Dexec.mainClass="tests.DogQueryDemo"
Example classes mentioned in the book also link directly to the sources on GitHub (unless you print the e-book, of course).
My writing background
I’ve written more than a few posts on my blog, mostly on technical topics, couple of them about JPA. Actually, this book is partially based on these frustrated experiences but is much more than a collection of blog posts as the research was much deeper. I was surprised it got to 200 pages in its first edition. My goal for the second edition was to updated it, extend it but, hopefully, also reduce and distill its original content.
I always felt like a writer – originally just to share ideas and experiences. Later I realized that writing helps me to clarify a lot of concepts to myself. For the same reasons (sharing and learning) I gave courses and talks. Preparing those is also kind of writing. So I hope both me and this book are not lost causes.
Feedback
When you work on a technical book, especially alone, it happens that some of the information is not exactly right and some might be plain wrong. Obviously, it is not my intention to mislead anyone. However, it may happen because the topic is not trivial. I study books and online resources, I test my solutions, I try to understand what is going on, but sometimes I may just understand something wrong. Sorry for that and please, if you know better, let me know. You can:
- either add an issue on the GitHub repo for the book,
- or just email me directly.
Obviously, factual errors are probably most crucial, but other suggestions are welcome too.