
ORMs vs SQL: The JPA Story - javinpaul
http://www.cforcoding.com/2009/05/orms-vs-sql-jpa-story.html
======
noelwelsh
I like the newer Scala frameworks, like Slick
([http://slick.typesafe.com/](http://slick.typesafe.com/)). They work with
tuples rather than classes. Fits much better with the relational model.

~~~
stormbrew
I am far more interested in this kind of approach to things these days than
ORMs or object databases. The relational model is a very powerful way of
looking at data and almost all ORMs wind up neutering all of that power,
leaving you with the absolute worst of all worlds.

What's needed is good (possibly object oriented) interfaces to relational
data, which is a very distinct concept from ORM.

~~~
jacques_chester
In my opinion, what's _actually_ needed is to realise that object orientation
is a dead end. We need relational programming languages.

ORMs can't work for a simple reason. They are trying to map from the world of
sets into the world of graphs. Sets are more expressive, so there is always a
good chance that there will be a lossy transformation.

 _This remark constitutes 100% of your RDA of cryptic ranting._

~~~
auvrw
total tangent, but in defense of graphs: it's worth noting that graphs are
actually a lot more expressive than they might appear at first glance. it's
possible to interpret linear orders, algebraic groups, or any other theory
written in finite language with graph theory (according to Marker's book on
model theory, which references Hodges' for details on the proof)

~~~
jacques_chester
Not tangential at all and I while I hate being wrong, I like learning new
things. Graphs _are_ very expressive. But most of the time, when you try to
express the domain model as a _tree_ (inheritance) it leads to muddiness
because most domain models are not truly tree-like. Then we try to express it
as graphs (composition), but that gives up the advantages of hierarchy.

If you instead express things as sets and subsets, you can enjoy the
advantages of both inheritance (DRY logic) and composition (numerous). Some
languages kinda sorta have this through mixins or modules. But not quite.

------
jacques_chester
[2009], for the confused.

~~~
twic
Quite a few of the detail-level problems in that post have indeed been fixed
by now. Not all of them. In practice, i find using Hibernate pretty painless,
but then i am the kind of person who actually reads documentation.

His final point still stands:

"If you're doing JPA, you still need to know databases and SQL. If you're
using a Web application framework, you still need to know the servlets API and
how HTTP works at least at a high level."

This is true of all sorts of ORM and noORM frameworks. You still need to
understand how databases work.

------
fusiongyro
I've been using Hibernate sans Java EE for about four years. I started using
it under JPA (again, without Java EE) about two years ago. Only in the last
few months have I been able to deploy a Java EE environment, and there, only
for a very small project, and the Java EE aspect was pretty minor, although
desirable and cool.

Hibernate does not require Java EE stuff. The "dynamic weaving" is provided by
Javassist (formerly provided by cglib, but cglib is apparently deprecated). No
complex setup here. Put the appropriate dependency in your pom and it
"magically" works.

Indeed, my biggest objection to Hibernate is the degree to which it relies on
magic. A lot of that magic is truly magic, in the sense that you are not
supposed to worry to hard about how it all works. If it did always just work,
it wouldn't be maddening when you try to figure out why it is going wrong only
to get slapped in the face by a fistful of hard magic.

For instance, the batch annotation, in pure, non-JPA Hibernate, is the fetch
"mode." There are several options like "join" and "subselect." Hibernate
defaults to an N+1 queries situation, but supplying "join" or "subselect"
instead isn't necessarily good enough to get the behavior you want. We had a
situation where no matter what we did in the Hibernate config, the behavior
was an N+1 query explosion. The problem turned out to be an innocuous-looking
log statement in the object model. Tracing in, it turned out that this log
statement was being invoked indirectly from the object's constructor, causing
the list to be "forced" before construction was complete. For some reason this
bypassed Hibernate's usual configuration. The solution was to delete the log
statement and take a lot of care not to touch anything that might be a
PersistentList from the constructor.

That kind of lesson, while trite, is very hard to apply in practice.
Especially when you have a set of developers working on the database and
object-relational mapping layer and another set working on the model.
Hibernate brings a lot of "gotchas." Shield's article hits on one of the more
onerous database-side ones, that you are informally forced into using
artificial keys, but there are enough oddball ramifications and restrictions
to go around that plenty of them spill out into the Java code.

I have positive feelings towards myBatis, but I have only used it for a few
edge cases in my Hibernate projects. While it is actually pretty easy to trick
Hibernate into returning real objects for native queries, the trouble doesn't
end there. It's very hard to do a complex SQL query from Hibernate without
running into the vague sensation that the Criteria API would be better. A few
hours later, you're back to building SQL strings, having read unsettling
absurdities in the documentation like "There is no explicit 'group by'
necessary in a criteria query."

myBatis's major advantage, in my conjectural opinion, is that it does not
pretend to liberate you from worrying about the database. As a database
developer, I am free to write the best query I can for a given situation,
liberally using the most esoteric features of my database. My peers in the
model can write exactly the interfaces they want to use. But they are not free
to imagine that they have the entire object graph available to them to manage
to the minutia at all times, and the ramifications of this loss on a group
working solely in the model must be great, and I haven't seen them yet. I see
storm clouds looming on that side of this tradeoff. It's annoying when I go to
a peer and say what they can and cannot do in a constructor or a bean property
getter/setter, but from then on they can still pretend that they have
everything, and the worst thing that happens is really untenable performance.
But everything works. myBatis, in contrast, is only too happy to give you back
an incomplete object tree. There is no "weaving" or "instrumentation" in what
comes back to support on-the-fly querying just because you accessed some
property. Again, it is a great strength (much, much less magic) but it's also
a great weakness. Your model guys aren't going to be able to ignore the
database with impunity.

I'd like to hear from a group that switched from Hibernate or JPA to myBatis
and how it worked out.

~~~
brianmcc
Very interesting; as someone's who been very happily using Ibatis with Java
and Spring for many years I've always been wary of Hibernate for just the
reasons you mention. The thought of ceding control over SQL to a framework so
extensively would give me sleepless nights, and my hunch has always been that
there will be a bunch of non-performant parent/child relation anti-patterns
basically baked in and waiting to pounce (if that's not too much of a mixed
metaphor...!).

~~~
nobullet
I understand why people don't like ORMs. But I don't understand people who
like iBatis: it is boilerplate like the hell. Imaging you have to separately
update mappings for SQL select, insert, update and delete query (and these
mappings are very long) for your entities.

For example, prepared statement for update looks like this:

    
    
      PreparedStatement ps = ...;
      ps.setLong(1, author.getUserId());
      ps.setLong(2, author.getStreamId());
      ps.setString(3, author.getNetwork());
      ps.setString(4, author.getIdInNetwork());
      ps.setString(5, author.getNote());
      ps.setString(6, author.getSocialId());
    

....

And manually counting questions is a normal practice when you add a field:

    
    
      static final String UPDATE = "UPDATE Table1 SET Domains = ?, TemplateId = ?, InternalJson = ? WHERE StreamID = ?";
      static final String INSERT = "INSERT INTO Config1 (UserID, StreamID, Domains, TemplateId, InternalJson) VALUES (?, ?, ?, ?, ?)";

~~~
fusiongyro
You have to pick your battles. It's convenient that Hibernate will do these
things for you, but I have seen lots of times when the order Hibernate wants
to remove something causes an integrity violation. For instance, a not-null
foreign key reference in a linking table; sometimes Hibernate seems to try
setting the value to null before deleting the referenced entity, leading to an
integrity violation. There have been times when I couldn't figure out how to
make Hibernate do this the right way (reversing the order of its deletes and
skipping the unnecessary set-null step) so I instead just lifted the
constraint. I hate when I have to do that, because ideally Hibernate should
just live with whatever schema I have given it.

Another example is trying to depend on CASCADE in the database. The settings
you need to make to get Hibernate to accept this are quite arcane and force
you to manually worry about list indexes in the Java code. Yet another example
of a place where Hibernate, which ought not be telling me how to make my
database or my Java code, instead winds up forcing me to take certain
decisions in both.

------
electrotype
Other active threads on this topic :

\- [http://stackoverflow.com/questions/17860161/replacing-a-
full...](http://stackoverflow.com/questions/17860161/replacing-a-full-orm-jpa-
hibernate-by-a-lighter-solution-recommended-pattern)

\- [https://groups.google.com/forum/?fromgroups#!topic/jooq-
user...](https://groups.google.com/forum/?fromgroups#!topic/jooq-
user/26Bd8wnwJgQ)

------
typicalrunt
I loved iBatis the moment I used it (some 8 years ago or so). And yet I always
felt like a black sheep because I liked working in SQL and also liked my "ORM"
to be a simple translation engine for results into a data structure that can
then be used by Java.

So I was happy to see this author come to the conclusion that iBatis is A Good
Thing, but I do wonder if we are still black sheep in a flock of Hibernate/JPA
enthusiasts.

------
kevbin
I like the JSF plug at the bottom that ends (kills?) the thread. If JSRs were
people, JSF would be in Pelican Bay.

