ORM (Object Relational Mapping) is a terrible anti-pattern that violates all principles of object-oriented programming, tearing objects apart and turning them into dumb and passive data bags. There is no excuse for ORM existence in any application, be it a small web app or an enterprise-size system with thousands of tables and CRUD manipulations on them. What is the alternative? SQL-speaking objects.
- Posted by: Yegor Bugayenko
- Posted on: January 05 2015 10:41 EST
- ORM Is an Offensive Anti-Pattern by Yannick Majoros on January 05 2015 13:16 EST
- ORM Is an Offensive Anti-Pattern by Erik Gollot on January 08 2015 13:29 EST
- ORM Is an Offensive Anti-Pattern by shawn spencer on January 16 2015 13:36 EST
- Don't quite your day job by Dawid Loubser on January 17 2015 10:36 EST
I sense another anti-pattern: the recurring low quality article full of unbacked claims.
FYI This post has been "debunked" on javalobby.
It also is part of the typical "i don't see the bigger picture" and "Those who don't learn from history are doomed to repeat it."
You mean, it's been debunked in the comments on dzone?
Or is there a debunking article?
In the comments.
Do you mean the comments on dzone? Or is there another counter-article?
Agree, this is the best way to describe such articles.
"It also is part of the typical "i don't see the bigger picture" and "Those who don't learn from history are doomed to repeat it.""
It is time consuming to explain why everything this Article assumes about JPA/ORM is flawed. Its much easier to dismiss the alternative.
"SQL-Speaking Objects"? which design pattern is this implementing?.
1. If the idea is for Post entity is to represent Post, why do we have db related functions in the object Post? Are we saying "One of the characteristics of an online post is to execute sql", well that statement is absurd. It failed OOP principles right there.
2. If the idea is for Post entity is to represent a record in the database. There is already a datastructure for it called the resultset, what exactly are we supposed to achive by creating one more layer to represent the same. If this is representing a DTO, again the same question, why does a DTO handle database SQL?
In short, the auther does not understand software design concepts. I know this is harsh to say, but articles like these deserve it.
And now an anti-article. ..
i am of the opinion rthat ORM is bad ...in any case.
i dont need an article or opinions :). and this article is very badly written.
ORM is one more middle man in your software that just adds one more point of failure and issues,
and i dont need you guys to tell me how wrong i m ... i m not. after builting walmart size ecommerce - we realized ORMs are for high school projects.
I would normally just ignore an article like this, but the number of learner software engineers who could negatively be influenced by this article (and others by the same author) compels me to respond:
One of the key points the author makes, is that normal ORM-based code (and please, this means JPA - not directly tying to one of the implementations, like Hibernate, Toplink, etc) is somehow not testable. Then he goes ahead and proposes a solution that is vastly less-testable. The author clearly does not understand two of the fundamental tenets of Java EE:
- Loose coupling - use CDI to @Inject things that you use, based only on their interface, and
- Never construct your own objects (that's the infrastructure's job). He explicitly creates an instance - using new - of his class "PgPosts" - and requires the developer to hand it a connection (hello? CDI?)
His solution is fundamentally non-unit-testable, unlike any modern JPA implementation.
The article author does not understand the a Java EE app server manages all non-functional (quality) requirements for you. This not only includes wiring objects together, but also things like pooling, caching, etc. As if to prove his ignorance, he shows us how we can use the best of 1980s OO thinking to implement some caching - something we already have for free with JPA.
The author then goes on to re-invent a woefully inadequate "caching" and "transactional" layer, blissfully unaware that Java EE properly solves these problems, without requiring all client code interacting with the "features" to be aware of them, and explicitly hook them up like his. Such a commong mistake: Re-invent things (badly) instead of spending some time reading about how Java EE works.
JPQL is not SQL
The mistakently claims that there is some connection between the JPA query language, and SQL. They are utterly different: The JPA query language merely queries the object graph (based on the class structure of the entities) - and is as at-home with a SQL back-end, as it is with an RDF one.
The article is very confused about what the responsibility of the objects actually are. They are some kind of hard-coded service / resultset hybrid, with no clear responsibility.
In JPA ("ORM"), your objects have the simple responsibility of just representing a data structure - a domain model, if you will. Using various services (to which we are loosely-coupled) we can do things with those objects, like
- Persist, Query their state from a datase (JPA)
- Map their state to/from XML, or JSON (JAX-RS)
- Use them as the model layer for the user interface (e.g. as values in a JSF bean), etc
Furthermore, if I decide, tomorrow, to persist them to a different technology - say a graph database, or RDF, or LDAP - nothing needs to change other than the implementation of EntityManager that my container gives my service objects via @Inject.
The author is clearly clamoring for the OO of old, where conceptually-week developers create misguided objecs stuffed with every possible, tightly-coupled responsibility known to man. The world where, when you place an order, and want to generate an invoice, you ask the order:
invoice = order.invoice();
News flash: The Java EE world has, for a long time, not advocated an object-oriented view, but a services-oriented view. This is clear from the proliferation of stateless EJB session beans, and JAX-RS resources, that handle the bulk of incoming service requests in the vast majority of Java EE systems out there. I rarely see stateful session beans - the OO approach - any more.
The objects we use to represent the exchanged information (to/from services), or the persisted domain model (internal) - which may or may not be the same, depending on your design - should just be that: a data model.
All further functionality should be provided by a services, each with a single responsibility. JPA is such a service. The author's approach fundamentally precludes this ability, and is a primary cause of the misery and complexity I see in the code of my clients on an almost daily bases.
+1 for debunking this kind of crap. I think it's useful to show that this is strongly criticized.