cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Durchholz, Joachim" <>
Subject RE: Advice needed: should I migrate from Hibernate to Cayenne?
Date Mon, 15 Aug 2011 09:16:48 GMT
Thanks to you and Christian, it has been very helpful. I'll wait the answers on Ebeans out
and decide then :-)

A few thoughts wrapping stuff up:

> There is no (clean) way to have a lazy, non-mandatory toOne relationship.

Ah. An interesting snag that I haven't hit yet.
Seems to be a quite rare case though. Making a to-one association eager usually isn't a performance
problem. Unless you're in a situation where you need per-column laziness, too, but at least
in my case, that's not a real issue. (The database server keeps 70% of the total database
in RAM anyway...)

> one of the devs basically said that he thought lazy fetching was a bad idea;
> an application should know at the beginning of the request what data it
> needs and fetch it all in one swoop.

Well, he's ignoring important use cases.
Besides, I don't see the point; if you have a way to reattach objects, you have thrown transactional
integrity out of the window anyway.

What's needed is a way to verify integrity on writeback time. I.e. declaratively identify
all the dependencies between data, and on commit, let the framework check that modified fields
don't depend on fields that were concurrently modified.

> Hibernate does have lazy loading now, but I still find it... finicky.
> It's way too easy to hit LazyInitializationException.

In my eyes, it's combining the disadvantages of strict discipline with the disadvantages of
missing transactional integrity.

Hibernate doesn't seem to be very clear about concepts in general. The whole codebase has
an "additive" feel - like lots of interfaces heaped on top of each other, and each new feature
written anew

> 4) runtime metadata.  You can get the metadata (mapping info) for
> entities in hibernate and in cayenne, but it's messed up in hibernate. :)

Heh. Been there, done that.
It *is* possible, and I got all the info that I needed. The awkwardness is because Hibernate
offers the info at the database layer, and you need to know how that translates back up to
the POJO level. Once you got that, it's all pretty straightforward though.

One caveat: I'd have to reengineer things a bit if I ever get into the situation where multiple
database fields map to a single Java property. It would be doable but I'd have to make a whole
lot of my own code understand multiple-field attributes, so I have left that as an exercise
to the reader :D

> 1) I do (kind of) like the annotation-based approach that is now
> available in hibernate.

Yes, those annotations are cool.
Unfortunately, they didn't cover everything that the .hbm.xml mechanism covers, so I went
back to .hbm.xml (with gritted teeth).
I understand that annotations are moving along, so this may be different today than it was
18 months ago.

> Not enough to abandon Cayenne + Cayenne Modeler, but if you like having
> all of the modeling info directly in your source (some do, some don't),
> or you like building your object and annotating on the fly, then this is nice.

I do.
But... well... it didn't work very well in Hibernate anyway.
And if it's the database that leads, you're tied to Hibernate's reverse engineering process,
which distributes a lot of relevant semantic information into a single monolithic configuration
file. Which plain sucks if you want the table-specific configuration in one place.

I guess Cayenne can't do worse than that :-)

> 2) Hibernate's implementation of inheritance is (probably) more complete
> than Cayenne's

An interesting point, but not for my current project. We're doing oldschool DB design here,
and inheritance doesn't really exist (except in the form of joined tables).

> Cayenne also supports vertical/"joined table inheritance", where you have
> one table for the superclass, and then a table for each subclass.

That's good enough for us.
After all, the database must be usable for ad-hoc SQL queries; fancy subclassing schemes don't
work too well with that.

>  Cayenne currently doesn't support "horizontal" inheritance (no table for the
> superclass; one table for each concrete subclass); hibernate does.  If you
> need that, you'll have to stick with hibernate (my condolences :).

You can always code around that. Use static functions for the common functionality across
the tables.
You don't get the encapsulation, but you do get the refactoring. (If people do ad-hoc queries,
you're in unencapsulated land anyway, so you had that loss already.)

> 2) Starting with a new technology is always a risk, but generally, I think
> your risk is reasonably low with Cayenne. If you're beating your head against
> the wall with Hibernate,

I am, else I wouldn't be looking into alternatives. Switching horses in mid-races is the worst
thing you can do, unless you are already banging your head against a stone wall.

> 4) ... maybe this is just me, but, I /usually/ try to avoid storing data
> that can be calculated.  Sometimes it's justified, if the calculation is expensive,

Heh. I'm 100% with you on that.

The issue is: people are scrolling through lists of orders. Many orders have a five-digit
number of positions. I can't have the DB calculate that on the fly - not if they're doing
a quick review over the last month's worth or orders, which would mean hundred thousands or
millions of rows that go into the sums to be shown.

The only way out that I really see is Oracle's "materialized views". But we want to be portable,
at least in principle, and materialized views aren't in any standard yet.

> With the right query cache strategy, it should be performant.

Well, the data changes rarely if ever. (I wouldn't be considering storing a sum field in the
Order table otherwise.)
I still am worried about performance.

Plus there's the other problem: People want to see the sums in ad-hoc SQL, so I'm pretty much
stuck with storing the sum in a table. (I could place it in a view, of course. Potentially
making it slow, plus query users will have to remember to use the view for SELECT and the
table for UPDATE.)

> 5) They aren't nested transactions; they are nested contexts.

Sorry, I was being sloppy with wording. I was thinking entirely from the perspective of code
that does data modifications, in which case the only relevant property of DB transations is
rollback, which is shared by contexts (as far as I understand contexts).

My guess is that contexts share the rollback semantics of nested transactions. They certainly
don't share the commit semantics, they'd fail with that on Persistence alone.


View raw message