Please stop making ORM frameworks

The two dozen ORM frameworks listed on java-source.net don’t even count the numerous homegrown ones used so passionately by their makers that they’re blind to all the other crap that’s out there. There’s simply too many bored developers trying to come up with a specific solution to a general problem and if it weren’t for Hibernate, who managed to somewhat thwart this growing resistance against writing queries, we’d have more ORM frameworks than MVC frameworks.

Anybody who still manually opens a Connection to a database and stuffs their beans by plunging through a ResultSet probably knows that they’re about five years behind where they should be. I’m no historian but to me the ORM boom started with JDO which to it’s credit, did give the idea a sort of legitimacy. It’s just too bad that the implementations were painfully slow and discounted so many scenarios that you ended up creating exceptions on almost every semi-complicated business operation. So what started promisingly as a step in the right direction yielded products like Java Ultra-Lite Persistence which – get this – wants you to write your mappings in Java code! Let’s substitute Java code that executes queries with Java code that creates mappings and then write additional Java code to use those mappings. It’s crap like this that comes out when developers are looking to satisfy their most immediate and gratifying needs.

No ORM talk is worth anything without a mention of IBatis. IBatis is a nice little innocent tool for those who’d rather write their queries in XML files rather than Java code. You’re still writing the queries but they’ll load the dependent objects for you provided you be nice and have the ability to know their source code like the back of your hand. It gained popularity largely because it stopped you from having to concatenate strings in your classes anymore. Lack of stored procedure support was an early issue and you just needed to write one too many handlers to support the data model, unless you were making it from absolute scratch. And besides, we developers are a spoiled bunch, we don’t want a framework to do some work for us, we want it to do all the work. IBatis tried to lessen the workload and did so to some degree but in the end the chances of you screwing up a query in IBatis is the same as if you were writing it in Java. I remember an IBatis committer once swearing on the mailing list that if he’d ever need to start a project, he’d use IBatis and Struts (this is when Webwork was out). I wonder if he still stands by his stance. IBatis has a slower learning curve than Hibernate which won over many a developer, including myself – for a short period of time.

Going off on a tangent now but if you use IBatis.NET – IBatis’ port for .NET – consider yourself lucky, because it appears that IBatis is almost exclusively focusing on their .NET product. The funny part about IBatis.NET is that half the questions on the mailing list pertain to getting Log4Net to log ANYTHING ANYWHERE. I too am guilty of starting one thread on the issue. May God forgive me.

I’m somewhat thankful to Sun for realizing that they dropped the ball on ORM and legitimizing Hibernate as a ground-breaking product by essentially copying them, adding annotations and slapping the label of Java Persistence API on it. The great part about this is that it puts an end to the joke that was CMP in pre-3.0 EJBs. Maybe now that ORM support is built-in to Java, I’m praying there won’t be half-thought-out products, worn-out XML configurations and “We are the best and greatest ORM framework in the world” chants coming from every direction in the Open Source malls. I’m no great software engineer or even a mediocre one at that, but it only takes a handful of brain cells to figure out that standardizing database access is a good thing and having numerous “choices” in such a practice can only be detrimental to the object.

So if you are even thinking in the back of your mind about writing an ORM framework for any reason, stop! Don’t waste your time, we need you to work on coming up with an MVC framework.

Advertisements

13 thoughts on “Please stop making ORM frameworks

  1. arsenalist

    ORM is complicated and any implementation of it will be complicated. Hibernate/TopLink are as comprehensive a solution there is right now.

    I don’t see how it “reduces your control over JDBC” since you can get a Connection object anytime and do whatever you like with it.

    Reply
  2. Jared

    “Going off on a tangent now but if you use IBatis.NET – IBatis’ port for .NET – consider yourself lucky, because it appears that IBatis is almost exclusively focusing on their .NET product.”

    What’s your basis for this? I’d just like to know as a heavy Java user of iBATIS and I’m hoping it’s unfounded.

    Reply
  3. arsenalist

    Jared, I’m a heavy IBatis Java user too. And that was a somewhat facetious remark. A few fellow consultants had begged IBatis to fix certain bugs having to do with ref cursors and the complaints were silently ignored. When a similar bug propped up on the .NET side, it was fixed immediately. I’ve noticed that the .NET team (Grabowski etc.) are much more active in making the product better than their Java counterparts. It’s just an observation.

    Just by looking at the user/dev mailing lists for both products, interest in the Java product has gone down. With JPA coming on the scene and formally defining ORM, users (including myself) will be hard pressed to use IBatis for a new project since it will almost be going against the grain, don’t you think? But for writing Java persistence code for existing databases, it’s still a good choice.

    Reply
  4. Rob

    arsenalist,

    If you don’t want other people to develop ORM ideas
    then I take it you are fully satisfied with JPA as a solution?

    Does this confidence in JPA extend to running outside a container?

    Are you confident that Extended Persistence Context is a good thing?

    Personally I think JPA has done a pretty decent job
    on the mapping side of ORM but for me there are some
    pretty interesting questions in regards the API and
    the architecture with EntityManager as essentially a
    user session object (ala Hibernate Session and Toplink ClientSession).

    BTW: How do you get a java.sql.Connection from JPA?
    I don’t see it being made available in the API at the moment.

    Thanks, Rob.

    Reply
  5. arsenalist

    I don’t know if I’m fully satisfied but I do think JPA is the answer to ORM woes. I think we’ve reached a point where not much more can be done to make ORM considerably better and if things need to improve, future versions of JPA will be able to provide the solutions.

    I don’t see anything wrong with Extended Persistence Context. I have JPA running in SE mode outside a container and it’s a breeze.

    Here’s how to access a Connection object using TopLink Essentials using a few different ways depending on your setup.

    Reply
  6. Rob

    Thanks for the link re getting a Connection from Toplink. The point I would make is that there is no standard way to do this in JPA (its Vendor specific at the moment).

    So, for using Extended Persistence Context outside a EJB or IoC container, how are you ‘managing’ the EntityManager objects?

    That is, I see the EntityManager as a user Session object (just like it is in Hibernate and Toplink) so the question becomes – have you written your own session management for EntityManager’s (ala Spring)?

    Reply
  7. arsenalist

    No, I haven’t written custom session management. I’ve “customized” the session by having an external connection pool to fit my needs but thats about it.

    I’ve used JPA/TopLink either inside a container or with Spring integration. Even the SE mode I was talking about used Spring and ClassPathXmlApplicationContext (instead of XmlWebApplicationContext).

    I suppose vendors that provide JPA implementations might have hooks to wire in custom session management (I know TopLink does, not sure about Hibernate) and you could use that feature if you feel the need to do so. I haven’t felt the need yet.

    Reply
  8. Rob

    We may be getting our wires crossed – I’m not sure (probably my fault, sorry).

    The session management I refer to is that EntityManager is a “User Session object” in the same sense that Hibernate Session and Toplink ClientSession are “User Session objects”. So for Extended Persistence Context there needs to be some session management of the EntityManager.

    That is, the EJB Container (or IoC Container/in your case Spring) provides some session management by injecting the appropriate EntityManager into your Stateful Session Beans (or similar, perhaps DAO objects in your case).

    So What? Who cares?
    – You probably don’t because Spring can automatically manage and inject the appropriate EntityManager for you – nice.
    – You also may not care if you always have a @Version property and create a EntityManager per Transaction (not using Extended Persistence Context). [Otherwise you may get lost updates – Spec section 3.4]

    So, have you ever queried back a large number of rows for processing? (Are they not all loaded into the “Persistence Context” which hence requires a fair bit of memory? How did you get around this issue?)

    Reply
  9. arsenalist

    Rob, I think you’re much more involved with whats going on here. Since I use Spring, I haven’t faced that issue yet. What do you mean by “large number” of rows? I have a kron job that loads about 2000 rows at a time for processing and goes on doing this continuously but since I start the JVM with big enough Xmx options, it hasn’t come back to bite me. At least not yet.

    Reply
  10. Rob

    “large number” from my perspective depends on the amount of memory you have. An example, could be to query 200,000 rows and write them to a file (csv, xml etc). For some 200,000 beans in the persistence context is a lot of memory and for some its acceptable.

    Ebean and Ibatis provide a callback mechanism (on a query) so that you can process one row at a time (without loading them all into a Persistence Context). A Hibernate person may suggest you look at using a StatelessSession (not sure about Toplink). It would be nice to have a solution in JPA…

    I am one of those mugs that wrote their own ORM 🙂 In my case thats Ebean which you can find at http://www.avaje.org. Probably all that means is that I have been looking fairly closely at JPA for some time. Perhaps I see problems with JPA that some don’t or perhaps I don’t see the solutions that some do – its hard to say at this stage (still trying to figure that out).

    The way I see it, many of the API issues with JPA are fixable and hopefully will be addressed soon (lack of batching control, Use of Connection for Savepoints and raw JDBC, large query support etc). Unfortunately for me, one of the ideas in Ebean is that it is session less (no detached/attached beans, no merge/flush etc). As this idea would potentially be a major shift in JPA’s design I can’t see this being adopted.

    So, today I remain a mug developing an ORM – time for a coffee!
    Cheers, Rob.

    Reply
  11. Agusti Pons

    I’ve always found the ORM tools a waste of time, control and resources.

    For simple Oracle connections (99% of the needs in web projects) I’ve used succesfully Microcalls. It’s a very simple approach using POJOs and XML.

    And no, it’s not another ORM framework 🙂

    http://www.microcalls.org

    Reply
  12. me

    Couple of comments on the large data set.

    Historically I’ve relied on a TopLink cursored stream to do what you noted (query 200,000 rows and write them to a file (csv, xml etc)). I haven’t yet tried this in JPA. But I’m assuming I can by calling a JPA extension for TopLink.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s