first a little bit of shameless selfpromotion: in one of the next
JavaMagazins you can read an article on Cayenne which shows up some
differences to Hibernate. Anyway it might be to long for you. My
background, I have used JDO before ages, was forced to use Toplink for
a while and then migrated to Hibernate with which I worked for a long
time. Early this year I decided to give Cayenne a try and was so
impressed that I build my app upon it.
I love the ease of use; I love that I didn't have to think on
LazyInitializationExcpetions (not for you if you are in the SE world)
and I love that I don't have to deal with proxies, which sometimes is
a pain (to debug). And the modeler is one of the most helpful tools
out there. I was used to configure everything by hand in Hibernate
world and thought I would never use a tool like the modeler. But the
modeler has the same priority in Cayenne world as the rest of the
framework, so it is as excellent as the rest. I never felt the need to
look into the xml configuration of Cayenne.
1. I'm in a J2SE project. There are wishes to convert that into J2EE, or at least partition the J2SE app into a J2EE-compatible service layer and a GUI. (There is also a nightly batch app that I don't see ever arriving in J2EE land. No use case for that.)
If it is a webapp you are planning (like me) you probably need to deal
with LazyInit..Ex as mentioned above. I felt this is all easier to
understand with Cayenne.
2. I can't take any risks. The project is in bad standing already because of all the time (more than a person-year) sunk into identifying and solving Hibernate hassles; another delay on that order of magnitude and I'm out of my current job. I can probably convince my higher-ups to sink another person-month into getting away from Hibernate, but I need to give solid guarantees.
Hibernate is able to solve edge cases of mappings. It is a real pain
there, but you can do every ugly code you can imagine. If you have
usual tables with relations and such, Cayenne is able to do all that
very well. In fact you simply need to define your table in the
modeler, choose your relations and the Java classes and everything is
already created for you. You can even create queries in the modeler.
All of that is very easy.
I have had some trouble with Hibernate mappings myself when they were
even pretty easy. I never felt such pain with Cayenne. There is some
stuff you need to learn of course, but I have made the experience that
the committers on this project are really nice and helpful. Even
"stupid" questions are answered in pretty quick time. You can do a
short lookup in the mail archives to prove that.
Now, after my project is shortly before go live, I felt that Cayenne
was the right choice for me. It was very straightforward for me to
learn and to use. Learning curve is pretty low.
3. I have no LOBs, no wide tables, and all bulk data goes over gigabit ethernet so I don't need no fieldwise laziness.
However, I have no experience with a framework that does not use bytecode generation, so I'm curious how the differences turn out in practice.
So... what do people think about pros and cons of runtime bytecode generation?
I did never really trust it. In todays world it is used widely but I
still do not trust it. I find it harder to debug. If you try look into
a persistent bag of hibernate, a db call is being made. Not really a
problem, but sometimes confusing. I have had many young people on my
projects starting with Hibernate after their university. They all were
puzzled on bytecode enhancement and I had tons to explain. Anyway, it
is somehow standard, but I still don't like it. I like more the "what
you code is what you get" way of live.
4. I'd like to ensure stuff like "Order.totalValue needs to be the sum of all associated OrderDetail.value fields".
"Interesting" aspects here:
- Other applications might have modified OrderDetail records during user think time. I'd prefer the ORM simply updating the totalValue to whatever is in the database over getting a concurrent modification complaint (unless the current app loaded the same OrderDetail and changed the value field to something different).
- The totalValue should get the correct value regardless of whether all pertinent OrderDetails were loaded. (This probably means running an UPDATE statement with SUM(value) in during flush/commit.)
- Various permutation about which fields in Order were modified by the current and the other application, and doing the Right Thing in each case (too much detail for a single post so I'm leaving that out for now).
BTW Hibernate doesn't do this, so supporting that use case would allow me to argue that we're not only getting rid of problems but actually getting something better than initially asked for :-)
Not sure that I understood everything right; but you have transactions
of course. And if two users deal with the same object, and user A does
an update, the update gets reflected on the object of user B.
Another thing which might be interesting for your case is that you can
deal with multiple datacontext. In basics you can load an object into
a datacontext X. You can load the same object into datacontext Y. Then
you are able to modify it in context X and as long as you don't commit
it, you can still work with the old values in datacontext Y. You can
do some pretty cool stuff with that concept and even move objects
Grab a beer and have a look at this:http://cayenne.apache.org/doc/datacontext.html
I guess you will like it very much.
5. Those nested transactions (savepoints) are pretty cool and would be a major advantage. Sometimes we do have a series of steps and need to roll back some but not all of them (the "wizard situation").
Are there caveats in that area, or can I go ahead and use that as a selling point without worrying about having to go back on that later?
Sorry can't tell anything on that, did not use it myself
6. How much manual work is involved in reverse engineering?
For Hibernate, I found that the tool is only marginally better than simply specifying everything by hand. Maybe automatic reverse engineering generally isn't worth the hassle; after all, the tool only sees a VARCHAR(1) but cannot know whether it's just a boolean in disguise or a one-character status code, let alone guess the actual mapping between database strings and Java enum values. (We have lots of such things in our tables.)
Honestly, you really should try it out. Download the package including
the modeler, start it, define a database connection and of you go. Its
pretty easy. I have tried it once and it worked like a charm for me. I
needed it only once and could not find any problems. Hopefully it is
fine for you too.
One thing worth mentioning: Hibernate supports more Caching
implementations like EHCache and others than Cayenne. Cayenne supports
OpenSymphony Cache and recently an EHCache integration has been
committed, but you have not the tons of caching systems supported by
Hibernate. Anyway it is "pretty easy" to integrate one yourself.
Anyway if you need that out of the box, better watch out