Persistence in Java Over the past years, I have gathered experience in the field
ID: 639530 • Letter: P
Question
Persistence in Java
Over the past years, I have gathered experience in the field of persistence abstraction in Java, using concepts such as EJB 2.0, Hibernate, JPA and home-grown ones. They seemed to me to have a steep learning curve and lots of complexity. In addition, as a big fan of SQL, I also thought that many abstraction models provide too much abstraction over SQL, creating concepts such as "criteria", "predicates", "restrictions" that are very good concepts, but not SQL.
The general idea of persistence abstraction in Java seems to be based on the Object-relational model, where RDBMS are somehow matched with the OO world. The ORM-debate has always been an emotional one, as there does not seem to exist a single solution that suits everyone - if such a solution can even exist.
jOOQ
My personal preference of how to avoid ORM-related problems is to stick to the relational world. Now the choice of data model paradigm should not be the topic of discussion as it is a personal preference, or a matter of what data model best suits a concrete problem. The discussion I would like to start is around my very own persistence tool called jOOQ. I designed jOOQ to provide most of the advantages modern persistence tools have:
A Domain Specific Language based on SQL
Source code generation mapping the underlying database schema to Java
Support for many RDBMS
Adding some features that few modern persistence tools have (correct me if I'm wrong):
Support for complex SQL - unions, nested selects, self-joins, aliasing, case clauses, arithmetic expressions
Support for non-standard SQL - stored procedures, UDT's, ENUMS, native functions, analytic functions
Please consider the documentation page for more details: http://www.jooq.org/learn.php. You will see that a very similar approach is implemented in Linq for C#, although Linq is not exclusively designed for SQL.
The Question
Now, having said that I'm a big fan of SQL, I wonder whether other developers will share my enthusiasm for jOOQ (or Linq). Is this kind of approach to persistence abstraction a viable one? What are the advantages / disadvantages you might see? How could I improve jOOQ, and what's missing in your opinion? Where did I go wrong, conceptually or practically?
Critical but constructive answers appreciated
I understand that the debate is an emotional one. There are many great tools out there that do similar things already. What I am interested in is critical but constructive feedback, based on your own experience or articles you may have read.
Explanation / Answer
I think you're on the right track and should continue with your solution. Some of the previous criticism is overly harsh, but some valid points are made.
I too have searched long and hard for a full-featured ORM solution that would fit my needs, but every solution I looked at came up short. Each has its pros and cons but none really did everything that I wanted. I agree with your criticism of these solutions - namely that they generally are complex and have a steep learning curve.
The top contender would have to be the de facto standard, Hibernate. It is full-featured, robust and well-tested. I respect it and appreciate it for what it is. Now, at the risk of offending half the programming community, I must also say that it is a bloated and complex piece of non-performant code. I've spent a fair amount of time poking around in its bowels, trying to debug and understand it, and I was not impressed with what I saw. Having said that, I would still recommend it as the starting point for anyone looking for a good ORM. It excels at simple CRUD, but I would not use it for performant bulk queries, such as data mining or number crunching.
Unfortunately, my application is more of the number crunching variety (though there is some CRUD too), so I decided to roll my own. I knew from the start that it would be sub par compared to the other solutions out there, but it would be good enough and give me the performance I needed. Now here's the really great part: it looks very much like your solution!
This is what I think you did most right: You stated your underlying beliefs as a kind of mission statement, and those beliefs are correct. I've obviously spent a fair amount of time thinking about this problem too, and it is a difficult one to solve. But as time goes on, I think the programming community comes to understand it better, and we will create better solutions. Kudos to all previous efforts (especially Hibernate), but I think we can do better.
Your solution better refines the problem, but it only solves part of it. I think that a layered approach may give us everything we want. What you have come up with/ IMO, is the foundation layer. As you have suggested, I think this layer is best automatically generated based on a database schema. It should be a very simple relational object model that maps directly onto the database and no more. You're right that data persists much longer than code, so at this level, data should drive code and not vice versa. It would support CRUD as well as performant bulk querying. I would probably implement some kind of L1 cache at this layer.
However, the thing that other ORM solutions excel at is the ability to define your objects in a manner that does not depend so much on the actual structure of the underlying database. For this functionality, I would create another layer. By necessity this layer becomes more abstract, hopefully simpler (at the expense of lost functionality), and builds on the previous layer. It might utilize an L2 cache.
I'm open to having more layers, but the key point for me is that by providing multiple entry points into the library, you can fulfill every need. For those that want a simple CRUD solution that maps directly to objects of their choosing, they can build on the top layer. For those looking for something more powerful and performant but willing to incur the added complexity, they can plug into the lower layer. I would not create a special query language, but instead would expose your query builder object for this purpose. And since the code is layered, that functionality naturally exists without special pass-through.
I think you do have an understanding of the space and aren't reinventing the wheel but rather have hit a slightly different niche. And frankly, this is a wheel that could use improvement anyway. You face an uphill battle contending against powerhouses of the past, but if your solution is good, and I think it's heading that way, then it will gain popularity on its own merits.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.