I’m not sure I’ve ever had such a long pause in blogging – not that I blog that often, but still. I either didn’t want to blog about how not to do things (current project I’m working on), or made various notes for myself in GitHub markdown – or, slowly but surely, working on my book. And this post is about the book.
The book is complete
I finally finished the first edition (and perhaps the last, but not necessarily) of my first technology book named Opinionated JPA with Querydsl. I started the book on December 16th, 2015. I planned to do it sometime during 2016. But September 2017 isn’t that late after all – especially with so little happening around JPA nowadays.
When I started I imagined a book around 100 pages but the thing grew over 200 in the end. Sure, I made font a bit bigger so it’s easy to read on ebook readers even in PDF format which still seems to be superior in presentation although less flexible on small readers. And even in this volume I didn’t cover all the things that are not covered in traditional JPA/ORM books.
Don’t mess with JPA, will ye?
I have to admit that I still don’t know JPA in and out although I can navigate the specification pretty well when I need to find something. There are features I simply refused to use, but for most of these I know they don’t solve the problems I typically have. If I must put it into a single point it would be better control over generated SQL.
Now I can hear those ORM purists and I believe I understand this topic reasonably well. I’ve heard about ORM being leaky abstraction, heard why it’s bad and when it’s actually good, I’ve read many articles on the topic and worked many hours using Java ORM solutions. If you want something extensive, there is always Ted Neward’s The Vietnam of Computer Science which was written in 2006 and hardly anything is out of date.
But I don’t care about academic ideas here, ORM is real, it’s used and I actually like many of its features. The least I like its effort to hide SQL from us though. I like its type conversion when compared to very poor low-level JDBC. I can live with unit-of-work as well but there are cases when it’s simply not suitable. And then you’re left on your own.
Streaming long query straight to a file or socket? Expect out of memory if you’re querying entities that fill up your persistence context eventually, even so you don’t need them there at all. Even without persistence context, it simply tries to create the whole list first before you can work with it. No cursor, nothing. Is this really such an unexpected and rare need?
Not compliant, not knowing it
I always firmly believed that if you work with SQL database one should know SQL. Whatever blanket you put over it, ignorance is hardly ever a good thing. I wrote quite a lot of articles on JPA. I saw first-hand what happens when you consider open-session-in-view a pattern instead of what it really is (antipattern). I tacked N+1 problem in context of pagination or thought about repeating problem of mapping enums to arbitrary database values. I realize that all the theory about specification crumbles in practice when you get into crossfire of various bugs in various JPA providers. I tried to modularize single entity model (persistence unit).
However I also liked improvements in JPA 2.1 and ORM still made my life easier in most situations. When I discovered that I can actually join on arbitrary value – e.g. map a foreign key as a plain value and then use join with on clause explicitly – I was blown away. That’s when I asked myself: “Why other people don’t try it too? Why we keep fighting ins and outs of relation mappings? Why we rely on convoluted configurations or particular providers to give us lazy to-one mapping?”
And then I decided to write a book about it. There was more to it – I wanted to lump more of my rogue ideas about JPA/ORM, staying still more or less concerned user of JPA, not a hater. I also wanted to see whether I can pull it off, all the way. I wanted to see how it is to self-publish a book on something like Leanpub. I didn’t expect much of a profit from that though, I realized this is no Perennial Seller as it’s too technology related and really niche, destined to be out-of-date rather soon.
But then during writing the book while I was testing my ideas both with Hibernate and EclipseLink, I found out that Hibernate does not support JOIN on root entity (e.g. join Dog d on …), only on entity paths (e.g. join person.dog). What the… how could they miss this thing?! And then it dawned on me… this is not part of a specification. My book more or less stopped for a couple of months, but eventually went on admitting openly that I’m not JPA compliant anymore. Good thing is that Hibernate eventually joined the club and since 5.1 they support this so called “ad hoc joins”.
Here we are
I’d just like to return to abstractions we talked about previously before I end this post. Right now I’m reading Patterns of Software by Richard P. Gabriel, written in 1996. We can argue that some of the problems are solved already, but I’d not be that sure. There’s a chapter called Abstraction Descant. I found out it really relates to me. Abstractions are important tools in our arsenal, but not everything can be solved by abstraction.
After reading this I realized I care even less whether ORM is leaky abstraction or not – it should be practical and not really that much how clean or perfect abstraction it is. Especially ORM being quite a big beast. It’s not a low level where abstractions shine best – like data structures, etc. I’m not going to say more, read that part from the book and make your own mind.
So – I’ve finished the book, hopefully not in vein. Kind of a longer blog post if you will. If you’re interested but not sure about it, you can grab it for free (and you can eventually pay later if you like it and feel it helped, I’m sure it’s possible :-)).