FAQ
Hi,

I am again responsible for making a cogent Cayenne vs Hibernate Comparison. Before I "reinvent the wheel" so-to speak with a new evaluation, I would like to find out if anyone has done a recent and fair comparison/evaluation (and has published it).

When I initially performed my evaluation of the two, it seemed like a very easy decision. While Hibernate had been widely adopted (and was on a number of job listings), it seemed like the core decision was made mostly because "everyone else was using it" (which I thought was a bit thin).

I base my decision on the fact that Cayenne (at the time) supported enough of the core ORM features that I needed, in addition to being very similar conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM implementations). Cayenne seems to support a more "agile" development model, while being as (or more) mature than EOF. (In my opinion. :) )

It seem like there is an explosion of standards, which appear to be driven by "camps" of opinions on the best practices for accomplishing abstraction of persistence supporting both native apps and highly distributed SOA's.

My vote is obviously for Cayenne, but I would definitely like to update my understanding of the comparison.

Thanks,
Joe

Search Discussions

  • Andrus Adamchik at Sep 6, 2010 at 12:21 pm
    There's been discussions on this list, but I haven't seen a full systematic comparison.

    When people ask me about this I usually frame this discussion as "what's unique about Cayenne", as I am not a Hibernate user and don't know it fine details. As I mentioned in the 3.0 announcement blog:

    https://blogs.apache.org/foundation/entry/apache_cayenne_v_3_0

    my list contains transparent and lightweight transactions, context nesting, remote object persistence, generic objects and dynamic mapping, modeling tools, and a few more things - friendly community, easy learning.

    Andrus
    On Sep 5, 2010, at 2:21 PM, Joe Baldwin wrote:
    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison. Before I "reinvent the wheel" so-to speak with a new evaluation, I would like to find out if anyone has done a recent and fair comparison/evaluation (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very easy decision. While Hibernate had been widely adopted (and was on a number of job listings), it seemed like the core decision was made mostly because "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough of the core ORM features that I needed, in addition to being very similar conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM implementations). Cayenne seems to support a more "agile" development model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven by "camps" of opinions on the best practices for accomplishing abstraction of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my understanding of the comparison.

    Thanks,
    Joe
  • Michael Gentry at Sep 6, 2010 at 2:22 pm
    Hi Joe,

    I don't have a Cayenne vs Hibernate comparison, but I can tell you a
    little about how things have shifted a bit where I work.

    Hibernate was the official ORM for non-WebObjects projects, which use
    EOF, of course. (We have a lot of legacy WO projects to maintain.)
    The WO people were much more interested in Cayenne since it mirrored
    EOF quite a bit. The non-WO people were much more interested in
    Hibernate because it was the "hip" ORM. Management chose Hibernate
    because it was the de-facto standard ORM in the Java community
    (everyone was using it) and they based part of that decision on the
    job search issue (who has Hibernate on their resume vs Cayenne).

    About 4-5 months ago, though, there was a small revolt by the
    developers, led in large part by the non-WO developers -- that is, the
    ones who wanted to use Hibernate because it was the standard ORM in
    the Java community (and had the buzz/mindshare behind it). Many of
    them were tired with problems they kept encountering with Hibernate
    (especially the lazy initialization exception). After many
    meetings/debates/etc, Cayenne got approved for general use and now
    several projects (including a large one that has a huge
    Hibernate-based backend already) are using Cayenne. The project I'm
    working on now consists of three Tapestry 5-based web applications
    with a common shared Cayenne-based core and that mirrors many of our
    other projects (we tend to separate out admin-restricted interfaces
    from user-exposed interfaces).
    From a personal perspective, the previous project I worked on is based
    on Tapestry 5 and Hibernate. (The developers voted at the beginning
    of the project between Hibernate and Cayenne and Cayenne lost by one
    vote.) There were numerous places in the application that we had to
    do things "backwards" due to Hibernate and the lazy initialization
    exception. For example, much of the application follows a
    wizard-based entry system and the user chooses their state on one page
    and then their county on another page. We couldn't call
    state.getCounties() on the county page because the state's Hibernate
    session was closed and would throw an exception. Things like that are
    natural in Cayenne and Just Work. What we had to do was construct a
    new query for the counties based upon the state. I joked around that
    with Hibernate, we might as well not have relationships because we
    don't use them because we can't follow them.

    mrg

    On Sun, Sep 5, 2010 at 2:21 PM, Joe Baldwin wrote:
    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison.  Before I "reinvent the wheel" so-to speak with a new evaluation, I would like to find out if anyone has done a recent and fair comparison/evaluation (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very easy decision.  While Hibernate had been widely adopted (and was on a number of job listings), it seemed like the core decision was made mostly because "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough of the core ORM features that I needed, in addition to being very similar conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM implementations).  Cayenne seems to support a more "agile" development model, while being as (or more) mature than EOF.  (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven by "camps" of opinions on the best practices for accomplishing abstraction of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my understanding of the comparison.

    Thanks,
    Joe
  • Theresa Stewart at Sep 6, 2010 at 2:32 pm
    Hi.

    I am very interested in having a concrete list of technical reasons
    developers prefer Cayene. I have worked with Cayene only so I have no
    real insight into the issues that caused the developers to revolt. A
    table perhaps that all could share. Perhaps one that developers where
    you work might care to add an entry or two (not too time consuming to
    contribute) You see my resume says Cayene but I apply to places that
    use Hibernate. So to say to them "here are the Hibernate issues, not
    from me but practioners" would go far I think. They still might
    respond "we selected hibernate so adapt" or they just might slowly
    transition over.

    Thank you,

    Theresa Stewart
    On Sep 6, 2010, at 9:21 AM, Michael Gentry wrote:

    Hi Joe,

    I don't have a Cayenne vs Hibernate comparison, but I can tell you a
    little about how things have shifted a bit where I work.

    Hibernate was the official ORM for non-WebObjects projects, which use
    EOF, of course. (We have a lot of legacy WO projects to maintain.)
    The WO people were much more interested in Cayenne since it mirrored
    EOF quite a bit. The non-WO people were much more interested in
    Hibernate because it was the "hip" ORM. Management chose Hibernate
    because it was the de-facto standard ORM in the Java community
    (everyone was using it) and they based part of that decision on the
    job search issue (who has Hibernate on their resume vs Cayenne).

    About 4-5 months ago, though, there was a small revolt by the
    developers, led in large part by the non-WO developers -- that is, the
    ones who wanted to use Hibernate because it was the standard ORM in
    the Java community (and had the buzz/mindshare behind it). Many of
    them were tired with problems they kept encountering with Hibernate
    (especially the lazy initialization exception). After many
    meetings/debates/etc, Cayenne got approved for general use and now
    several projects (including a large one that has a huge
    Hibernate-based backend already) are using Cayenne. The project I'm
    working on now consists of three Tapestry 5-based web applications
    with a common shared Cayenne-based core and that mirrors many of our
    other projects (we tend to separate out admin-restricted interfaces
    from user-exposed interfaces).

    From a personal perspective, the previous project I worked on is based
    on Tapestry 5 and Hibernate. (The developers voted at the beginning
    of the project between Hibernate and Cayenne and Cayenne lost by one
    vote.) There were numerous places in the application that we had to
    do things "backwards" due to Hibernate and the lazy initialization
    exception. For example, much of the application follows a
    wizard-based entry system and the user chooses their state on one page
    and then their county on another page. We couldn't call
    state.getCounties() on the county page because the state's Hibernate
    session was closed and would throw an exception. Things like that are
    natural in Cayenne and Just Work. What we had to do was construct a
    new query for the counties based upon the state. I joked around that
    with Hibernate, we might as well not have relationships because we
    don't use them because we can't follow them.

    mrg


    On Sun, Sep 5, 2010 at 2:21 PM, Joe Baldwin
    wrote:
    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate
    Comparison. Before I "reinvent the wheel" so-to speak with a new
    evaluation, I would like to find out if anyone has done a recent
    and fair comparison/evaluation (and has published it).

    When I initially performed my evaluation of the two, it seemed like
    a very easy decision. While Hibernate had been widely adopted (and
    was on a number of job listings), it seemed like the core decision
    was made mostly because "everyone else was using it" (which I
    thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported
    enough of the core ORM features that I needed, in addition to being
    very similar conceptually to NeXT EOF (which was the first stable
    Enterprise-ready ORM implementations). Cayenne seems to support a
    more "agile" development model, while being as (or more) mature
    than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be
    driven by "camps" of opinions on the best practices for
    accomplishing abstraction of persistence supporting both native
    apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to
    update my understanding of the comparison.

    Thanks,
    Joe
  • Joe Baldwin at Sep 6, 2010 at 3:12 pm
    Michael,

    (IMHO) Your anecdote reveals a not-unfamiliar trend. (And with no ill-will towards Hibernate) ... it seems that Hibernate was embraced by project managers because they saw a lot of resumes with Hibernate, and programmers learned Hibernate because a lot of Project Managers asked for Hibernate.

    When I ask the explicit question "why", the answer seems to reduce *very* quickly to "because everyone else is using it". (Which sounded to me to be the same complexity of thought behind going with "Microsoft Windows" and "VHS", and I think to some degree "McDonnald's Hamburgers"). So it was not sufficiently convincing.

    I started out with Objective-C, Webobjects, and EOF in 1999, and at the time they were some of the most advanced software technologies available. The design patterns were mature and stable, and therefore (IMO again) an excellent place to start for Cayenne.

    BTW, the last official report I heard from Apple is of the major milestone that music purchases via iTunes have surpassed CD sales. This is significant since iTunes is built with Webobjects & EOF. (I would consider a successful multi-billion dollar three-tier enterprise system to be a worthy 'proof of concept', but unfortunately Webobjects is considered to be "dead" in the developer community.)

    Thanks for your input, I think the amount of "workarounds" one has to do in a project (as you report with Hibernate relationships) is a significant measure of maturity and/or brittleness.

    Joe



    On Sep 6, 2010, at 10:21 AM, Michael Gentry wrote:

    Hi Joe,

    I don't have a Cayenne vs Hibernate comparison, but I can tell you a
    little about how things have shifted a bit where I work.

    Hibernate was the official ORM for non-WebObjects projects, which use
    EOF, of course. (We have a lot of legacy WO projects to maintain.)
    The WO people were much more interested in Cayenne since it mirrored
    EOF quite a bit. The non-WO people were much more interested in
    Hibernate because it was the "hip" ORM. Management chose Hibernate
    because it was the de-facto standard ORM in the Java community
    (everyone was using it) and they based part of that decision on the
    job search issue (who has Hibernate on their resume vs Cayenne).

    About 4-5 months ago, though, there was a small revolt by the
    developers, led in large part by the non-WO developers -- that is, the
    ones who wanted to use Hibernate because it was the standard ORM in
    the Java community (and had the buzz/mindshare behind it). Many of
    them were tired with problems they kept encountering with Hibernate
    (especially the lazy initialization exception). After many
    meetings/debates/etc, Cayenne got approved for general use and now
    several projects (including a large one that has a huge
    Hibernate-based backend already) are using Cayenne. The project I'm
    working on now consists of three Tapestry 5-based web applications
    with a common shared Cayenne-based core and that mirrors many of our
    other projects (we tend to separate out admin-restricted interfaces
    from user-exposed interfaces).

    From a personal perspective, the previous project I worked on is based
    on Tapestry 5 and Hibernate. (The developers voted at the beginning
    of the project between Hibernate and Cayenne and Cayenne lost by one
    vote.) There were numerous places in the application that we had to
    do things "backwards" due to Hibernate and the lazy initialization
    exception. For example, much of the application follows a
    wizard-based entry system and the user chooses their state on one page
    and then their county on another page. We couldn't call
    state.getCounties() on the county page because the state's Hibernate
    session was closed and would throw an exception. Things like that are
    natural in Cayenne and Just Work. What we had to do was construct a
    new query for the counties based upon the state. I joked around that
    with Hibernate, we might as well not have relationships because we
    don't use them because we can't follow them.

    mrg

    On Sun, Sep 5, 2010 at 2:21 PM, Joe Baldwin wrote:
    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison. Before I "reinvent the wheel" so-to speak with a new evaluation, I would like to find out if anyone has done a recent and fair comparison/evaluation (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very easy decision. While Hibernate had been widely adopted (and was on a number of job listings), it seemed like the core decision was made mostly because "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough of the core ORM features that I needed, in addition to being very similar conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM implementations). Cayenne seems to support a more "agile" development model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven by "camps" of opinions on the best practices for accomplishing abstraction of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my understanding of the comparison.

    Thanks,
    Joe
  • Robert Zeigler at Sep 6, 2010 at 3:07 pm
    Hi Joe,

    First, this e-mail wound up a lot longer than I intended, apologies! The short version is: having used both a fair bit, I prefer cayenne, but they both have strengths and weaknesses. Most of this e-mail details what I view as weaknesses in Hibernate. :)

    On to the long version!

    I still know cayenne better than hibernate, but I've used both extensively (2+ years of experience with hibernate, on a fairly large system with > 80 tables; I've used cayenne for > 5 years now). I don't have time right now to put together a systematic comparison, but here are a few notes:

    Hibernate: POJO - some people love it, some hate it. I'm in the latter camp. You lose out on a lot of code-reuse, debugging is more difficult, and it necessitates constructs like hibernate proxies, which are a PITA to deal with, IMO.
    Cayenne: interface (inheritance, in practice)-based design. Some people don't like the domain-structure constraints it imposes. I find it makes debugging easier and results in more code re-use. And, no proxies. Objects are what they are. More importantly, objects are what you think they are (in hibernate-land, I've had code like the following:

    public class MyObject2 extends MyObject1 {...}

    elsewhere:

    MyObject1 someobj = someCodeThatReturnsMyObject1();
    if (MyObject2.class.isInstance(someobj)) {
    ((MyObject2)someobj).callMyObject2Method();
    }

    And the above code will throw a cast class exception. Yup. That's right. Because someobj is a proxy. A call to getClass() returns the getClass() of the underlying object (an instance of MyObject2), but someobj, the proxy, technically only implements MyObject1. So you get a ClassCastException. Other variants include your code not executing at all, even when you know that someobj /should/ be an instance of MyObject2. The code above is, of course, contrived, but I've hit this in numerous "real world" scenarios.

    Hibernate & Cayenne both support "lazy fetching" in some form, but Cayenne's support is far superior, IMO (with bonafide faulting, etc.). This is a function, I think, of having supported it far longer (this was initially the reason that I used Cayenne rather than Hibernate). Google "hibernate lazyinitializationexception" to see what I mean. In particular, if you go the hibernate route, be very /very/ careful what you do in event listeners (pre/post commit, etc.) because it's very easy to hit exceptions there. Basically, I find that in Hibernate, event listeners are just barely better than useless. A great idea, but you can't really /do/ anything useful in them. And even the 3rd party modules, written by long-time hibernate developers, hit these edge cases (eg: hibernate envers for entity auditing/logging has had issues reported where they hit issues with lazyinitializationexception from using lifecycle listeners). The hibernate "way" was originally to not support lazy fetching at all; either all of the data you needed came into the request/session at once, or it wasn't there at all. This probably resulted in more /performant/ code (fewer queriest/hits to the db, for instance), but is basically not feasible in the world of 3rd party modules/integration/development: it's not always possible to know exactly what information you need at the beginning of, eg, a web request.

    I have to give kudos to the hibernate team for the extremely flexible mappings they support. I find cayenne mapping more /intuitive/ (thanks in part to the modeler), but there are edge mapping cases that are supported in hibernate that are not, to the best of my knowledge, supported in cayenne (cayenne 3.0 improves this discrepancy, though). As an example, hibernate supports more inheritance modeling schemes (table per concrete subclass, table per class, single table) than does cayenne, although cayenne 3.0 has improved in this regard. For simple mapping, hibernate may even be more straightforward than cayenne due to it's ability to analyze your domain objects and figure out the appropriate tables, etc. to create. On the other hand, I personally shy away from having hibernate auto-create my table structure. I find it results in less thinking about what's really occurring at the db level. Although that is, to a greater or lesser extent, the point of an ORM system, it's my opinion that it's still important to think about how the data is physically mapped at the db level. (I should note that you can specify the exact mapping characteristics in hibernate. But my observation is that the tendency is to let hibernate "do it's thing" until you find a problem with the way it did it's thing, and you tell hibernate the "right way" to do it).

    Metadata: There's no "dbentity" vs. "objentity" separation. That's great for some people... but really too bad. :) My personal experience is that cayenne's meta-data support is more accessible and richer than Hibernate's, but that's probably a function, at least in part, of familiarity with the frameworks.

    pks: Cayenne's approach is: "these are a database-artifact and shouldn't pollute your data model, unless you need them to be there". Hibernate's approach is: "pk's are an integral part of your domain object" (for the most part).

    ObjectContext vs. Session. Session is a poor man's ObjectContext. ;) That's an opinion, of course. But. On the surface, these two objects do similar sorts of things: save, commit transactions, etc. But in reality, they are completely different paradigms. In Cayenne, an ObjectContext is very much a "sandbox" where you can make changes, roll them back, commit them, etc. A hibernate session is more like a command queue: you instruct it to update, save, or delete specific objects, ask it for "Criteria" for criteria-based queries, etc. They may sound similar but there's a big difference in how you use them. Basically, hibernate doesn't have the notion of "modified or new object that needs to be saved at some point in the future, but which I should retain a reference to now." :) In cayenne, you can do something like this:

    void someMethod(ObjectContext context) {
    context.newObject(SomePersistentObject.class).setSomeProperty("foo");
    ...
    }

    Now when that particular context is committed, a new instance of SomePersistentObject will be committed, without the calling code having to know about it. Arguably, this is a method witih "side effects" that should be avoided, but there are legitimate use cases for this. Consider a recent example I encountered. A hibernate project I work on manages a set of "projects". Changes to projects are audited, except when the project is first created/in state "project_created" (a custom flag, unrelated to hibernate). I recently needed to add support for one auditing operation: record the date of creation, and the user who created the project. WIthout getting into gory details, the simplest way to do this would have been to modify the service responsible for creating all project types, along the lines of this (how I would do this in cayenne):

    public <T extends Project> T createProject(Class<T> type) {
    T project = codeToCreateProject();
    Audit a = objectContext.newObject(Audit.class);
    a.setProject(project);
    a.setMessage("Project Created");
    a.setDate(new Date());
    return project;
    }

    Notes: the project creator is not (and cannot, due to design constraints) commit the project to the database at this point in the code. That's fine in cayenne: as long as the calling code is using the same object context (it always would be in my case), the Audit object would be committed at the same time the project is, and life would be happy. But the project is not cayenne. It is hibernate. So:

    public <T extends Project> T createProject(Class<T> type) {
    T project = codeToCreateProject();
    Audit a = new Audit();
    a.setProject(project);
    a.setMessage("Project Created");
    a.setDate(new Date());
    return project;
    }

    Except, what happens to a? The answer is: nothing. It isn't ever saved. It would be, if Project had a reverse relationship to audit (List<Audit> getAudits()), that was set to cascade the "save" and "update" operations.
    But Project didn't/doesn't, and I wasn't allowed to add it. There was no way to tell hibernate: "Look, I've got this object, and I wan't you to save it, but, not right this second". You can call: session.save(a). But that results in an immediate commit the audit object (and ONLY the audit object!), so if the project isn't yet persisted to the db, you get a relationship constraint violation, trying to save a relationship to an unsaved object. There's also a session.persist(a) method, part of EJB3 spec, which is theoretically like cayenne's "register", but in hibernate, its functionally equivalent (or very nearly so) to session.save(a): it triggers an immediate commit to the database (at least in our application setup). There is no equivalent to cayenne's "context.register(a)". I finally solved this issue via life cycle event listeners, and it was a pain (you have to be /extremely/ careful about what you do in hibernate event listeners. In particular, read operations that result in a hit to the database will cause you major grief, even if you don't modify anything, and modification of any kind is next to impossible).

    All that said, there are /some/ good ideas in hibernate. :) For one thing, Cayenne's /requirement/ that two objects with a shared relationship be in the same ObjectContext can cause grief, particularly in web applications. Imagine you have a form to create a new object of type Foo. Foo has a relationship to Bar. You may not want to register this object with the context until you know that the new Foo object is a "valid" object (lest you wind up with "dirty" objects polluting subsequent commits, using an ObjectContext-per-user session paradigm). But you can't do that: when you set the Bar relationship, Foo will be registered with the context. That's usually fine... you can usually rollback the changes... but it does mean sometimes having to think carefully about what "state" your objects are in.

    I've yet to find the "perfect" ORM. THere isn't one, as far as I'm concerned, b/c there's simply a mismatch between the db model and the object model that will result in tradeoffs. But I find Cayenne far easier to learn and use than Hibernate.

    Cheers,

    Robert
    On Sep 5, 2010, at 9/51:21 PM , Joe Baldwin wrote:

    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison. Before I "reinvent the wheel" so-to speak with a new evaluation, I would like to find out if anyone has done a recent and fair comparison/evaluation (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very easy decision. While Hibernate had been widely adopted (and was on a number of job listings), it seemed like the core decision was made mostly because "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough of the core ORM features that I needed, in addition to being very similar conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM implementations). Cayenne seems to support a more "agile" development model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven by "camps" of opinions on the best practices for accomplishing abstraction of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my understanding of the comparison.

    Thanks,
    Joe
  • Joe Baldwin at Sep 6, 2010 at 4:16 pm
    Robert,

    All I can say is "wow", thanks for the insights. This is especially important because you use both frameworks.

    Please let me ask some more questions. (Note: as I said, I was initially attracted to Cayenne because it had familiar design patterns to EOF, which I thought was fairly mature at the time, so I may not understand the Hibernate-way of "thinking").

    RE ObjectContext vs Session
    I may be mixed up but it sounds like the ObjectContext is similar in concept to EOF. It sounds like you are saying that among other things the Hibernate-Session makes simple transactional tasks much more difficult and may even interfere with a Factory-Method approach to building data objects within a transaction.

    RE Lazy Fetching
    If I have the concept correct, this is another term for what EOF calls "faulting" behavior. IMO optimized/smart faulting behavior is the single most important reason to use an ORM. The conceptual differences between a RDBMS and an OO language can result in massive problems with a macro design, one that a good ORM solves via intelligent faulting algorithms. I had just assumed that this was a "moot" issue based on the fundamental solutions offered by EOF. Are there any essential differences in features of "Lazy Fetching" that you can point out?

    RE dbentity/objentity differences

    Is the reason associated with the maturity of the "faulting" behavior (or something else)?

    RE Google "hibernate lazyinitializationexception" to see what I mean.

    OK, I googled it as you suggested, and found a few (what I call dissertations) on the subject that suggest that Hibernate does not have a cogent "faulting" design, and that the Hibernate-Session is not as mature a model for transactions as is Cayenne's ObjectContext (if I understand the issues). Is this correct?

    Correct me if I am wrong (please :) ), but it is starting to sound similar to the discussions of C++ garbage collection vs Java garbage collection (i.e. C++ doesn't really embrace garbage collection as a problem that should be handled by anyone but the programmer)

    Thanks again for your input,
    Joe













    On Sep 6, 2010, at 11:06 AM, Robert Zeigler wrote:

    Hi Joe,

    First, this e-mail wound up a lot longer than I intended, apologies! The short version is: having used both a fair bit, I prefer cayenne, but they both have strengths and weaknesses. Most of this e-mail details what I view as weaknesses in Hibernate. :)

    On to the long version!

    I still know cayenne better than hibernate, but I've used both extensively (2+ years of experience with hibernate, on a fairly large system with > 80 tables; I've used cayenne for > 5 years now). I don't have time right now to put together a systematic comparison, but here are a few notes:

    Hibernate: POJO - some people love it, some hate it. I'm in the latter camp. You lose out on a lot of code-reuse, debugging is more difficult, and it necessitates constructs like hibernate proxies, which are a PITA to deal with, IMO.
    Cayenne: interface (inheritance, in practice)-based design. Some people don't like the domain-structure constraints it imposes. I find it makes debugging easier and results in more code re-use. And, no proxies. Objects are what they are. More importantly, objects are what you think they are (in hibernate-land, I've had code like the following:

    public class MyObject2 extends MyObject1 {...}

    elsewhere:

    MyObject1 someobj = someCodeThatReturnsMyObject1();
    if (MyObject2.class.isInstance(someobj)) {
    ((MyObject2)someobj).callMyObject2Method();
    }

    And the above code will throw a cast class exception. Yup. That's right. Because someobj is a proxy. A call to getClass() returns the getClass() of the underlying object (an instance of MyObject2), but someobj, the proxy, technically only implements MyObject1. So you get a ClassCastException. Other variants include your code not executing at all, even when you know that someobj /should/ be an instance of MyObject2. The code above is, of course, contrived, but I've hit this in numerous "real world" scenarios.

    Hibernate & Cayenne both support "lazy fetching" in some form, but Cayenne's support is far superior, IMO (with bonafide faulting, etc.). This is a function, I think, of having supported it far longer (this was initially the reason that I used Cayenne rather than Hibernate). Google "hibernate lazyinitializationexception" to see what I mean. In particular, if you go the hibernate route, be very /very/ careful what you do in event listeners (pre/post commit, etc.) because it's very easy to hit exceptions there. Basically, I find that in Hibernate, event listeners are just barely better than useless. A great idea, but you can't really /do/ anything useful in them. And even the 3rd party modules, written by long-time hibernate developers, hit these edge cases (eg: hibernate envers for entity auditing/logging has had issues reported where they hit issues with lazyinitializationexception from using lifecycle listeners). The hibernate "way" was originally to not support lazy fetching at all; either all of the data you needed came into the request/session at once, or it wasn't there at all. This probably resulted in more /performant/ code (fewer queriest/hits to the db, for instance), but is basically not feasible in the world of 3rd party modules/integration/development: it's not always possible to know exactly what information you need at the beginning of, eg, a web request.

    I have to give kudos to the hibernate team for the extremely flexible mappings they support. I find cayenne mapping more /intuitive/ (thanks in part to the modeler), but there are edge mapping cases that are supported in hibernate that are not, to the best of my knowledge, supported in cayenne (cayenne 3.0 improves this discrepancy, though). As an example, hibernate supports more inheritance modeling schemes (table per concrete subclass, table per class, single table) than does cayenne, although cayenne 3.0 has improved in this regard. For simple mapping, hibernate may even be more straightforward than cayenne due to it's ability to analyze your domain objects and figure out the appropriate tables, etc. to create. On the other hand, I personally shy away from having hibernate auto-create my table structure. I find it results in less thinking about what's really occurring at the db level. Although that is, to a greater or lesser extent, the point of an ORM system, it's my opinion that it's still important to think about how the data is physically mapped at the db level. (I should note that you can specify the exact mapping characteristics in hibernate. But my observation is that the tendency is to let hibernate "do it's thing" until you find a problem with the way it did it's thing, and you tell hibernate the "right way" to do it).

    Metadata: There's no "dbentity" vs. "objentity" separation. That's great for some people... but really too bad. :) My personal experience is that cayenne's meta-data support is more accessible and richer than Hibernate's, but that's probably a function, at least in part, of familiarity with the frameworks.

    pks: Cayenne's approach is: "these are a database-artifact and shouldn't pollute your data model, unless you need them to be there". Hibernate's approach is: "pk's are an integral part of your domain object" (for the most part).

    ObjectContext vs. Session. Session is a poor man's ObjectContext. ;) That's an opinion, of course. But. On the surface, these two objects do similar sorts of things: save, commit transactions, etc. But in reality, they are completely different paradigms. In Cayenne, an ObjectContext is very much a "sandbox" where you can make changes, roll them back, commit them, etc. A hibernate session is more like a command queue: you instruct it to update, save, or delete specific objects, ask it for "Criteria" for criteria-based queries, etc. They may sound similar but there's a big difference in how you use them. Basically, hibernate doesn't have the notion of "modified or new object that needs to be saved at some point in the future, but which I should retain a reference to now." :) In cayenne, you can do something like this:

    void someMethod(ObjectContext context) {
    context.newObject(SomePersistentObject.class).setSomeProperty("foo");
    ...
    }

    Now when that particular context is committed, a new instance of SomePersistentObject will be committed, without the calling code having to know about it. Arguably, this is a method witih "side effects" that should be avoided, but there are legitimate use cases for this. Consider a recent example I encountered. A hibernate project I work on manages a set of "projects". Changes to projects are audited, except when the project is first created/in state "project_created" (a custom flag, unrelated to hibernate). I recently needed to add support for one auditing operation: record the date of creation, and the user who created the project. WIthout getting into gory details, the simplest way to do this would have been to modify the service responsible for creating all project types, along the lines of this (how I would do this in cayenne):

    public <T extends Project> T createProject(Class<T> type) {
    T project = codeToCreateProject();
    Audit a = objectContext.newObject(Audit.class);
    a.setProject(project);
    a.setMessage("Project Created");
    a.setDate(new Date());
    return project;
    }

    Notes: the project creator is not (and cannot, due to design constraints) commit the project to the database at this point in the code. That's fine in cayenne: as long as the calling code is using the same object context (it always would be in my case), the Audit object would be committed at the same time the project is, and life would be happy. But the project is not cayenne. It is hibernate. So:

    public <T extends Project> T createProject(Class<T> type) {
    T project = codeToCreateProject();
    Audit a = new Audit();
    a.setProject(project);
    a.setMessage("Project Created");
    a.setDate(new Date());
    return project;
    }

    Except, what happens to a? The answer is: nothing. It isn't ever saved. It would be, if Project had a reverse relationship to audit (List<Audit> getAudits()), that was set to cascade the "save" and "update" operations.
    But Project didn't/doesn't, and I wasn't allowed to add it. There was no way to tell hibernate: "Look, I've got this object, and I wan't you to save it, but, not right this second". You can call: session.save(a). But that results in an immediate commit the audit object (and ONLY the audit object!), so if the project isn't yet persisted to the db, you get a relationship constraint violation, trying to save a relationship to an unsaved object. There's also a session.persist(a) method, part of EJB3 spec, which is theoretically like cayenne's "register", but in hibernate, its functionally equivalent (or very nearly so) to session.save(a): it triggers an immediate commit to the database (at least in our application setup). There is no equivalent to cayenne's "context.register(a)". I finally solved this issue via life cycle event listeners, and it was a pain (you have to be /extremely/ careful about what you do in hibernate event listeners. In particular, read operations that result in a hit to the database will cause you major grief, even if you don't modify anything, and modification of any kind is next to impossible).

    All that said, there are /some/ good ideas in hibernate. :) For one thing, Cayenne's /requirement/ that two objects with a shared relationship be in the same ObjectContext can cause grief, particularly in web applications. Imagine you have a form to create a new object of type Foo. Foo has a relationship to Bar. You may not want to register this object with the context until you know that the new Foo object is a "valid" object (lest you wind up with "dirty" objects polluting subsequent commits, using an ObjectContext-per-user session paradigm). But you can't do that: when you set the Bar relationship, Foo will be registered with the context. That's usually fine... you can usually rollback the changes... but it does mean sometimes having to think carefully about what "state" your objects are in.

    I've yet to find the "perfect" ORM. THere isn't one, as far as I'm concerned, b/c there's simply a mismatch between the db model and the object model that will result in tradeoffs. But I find Cayenne far easier to learn and use than Hibernate.

    Cheers,

    Robert
    On Sep 5, 2010, at 9/51:21 PM , Joe Baldwin wrote:

    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison. Before I "reinvent the wheel" so-to speak with a new evaluation, I would like to find out if anyone has done a recent and fair comparison/evaluation (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very easy decision. While Hibernate had been widely adopted (and was on a number of job listings), it seemed like the core decision was made mostly because "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough of the core ORM features that I needed, in addition to being very similar conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM implementations). Cayenne seems to support a more "agile" development model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven by "camps" of opinions on the best practices for accomplishing abstraction of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my understanding of the comparison.

    Thanks,
    Joe
  • Robert Zeigler at Sep 6, 2010 at 6:03 pm

    On Sep 6, 2010, at 9/611:16 AM , Joe Baldwin wrote:

    Robert,

    All I can say is "wow", thanks for the insights. This is especially important because you use both frameworks.

    Please let me ask some more questions. (Note: as I said, I was initially attracted to Cayenne because it had familiar design patterns to EOF, which I thought was fairly mature at the time, so I may not understand the Hibernate-way of "thinking").
    I never used EOF, and I started using hibernate as a client requirement a couple years back, coming to it from a "cayenne" perspective, so be aware there's some bias here. :)
    RE ObjectContext vs Session
    I may be mixed up but it sounds like the ObjectContext is similar in concept to EOF. It sounds like you are saying that among other things the Hibernate-Session makes simple transactional tasks much more difficult and may even interfere with a Factory-Method approach to building data objects within a transaction.
    According to my (very limited) knowledge of EOF, ObjectContext is similar. :) Session is somewhat similar. This is from the Session api docs:

    A typical transaction should use the following idiom:

    Session sess = factory.openSession();
    Transaction tx;
    try {
    tx = sess.beginTransaction();
    //do some work
    ...
    tx.commit();
    }
    catch (Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
    }
    finally {
    sess.close();
    }

    So they are demonstrating the use of a transaction to perform multiple units of work. Of note, they don't mention here that you would normally either call: session.flush() (before tx.commit) or else your session would be set to "AUTO_FLUSH". Basically, that means that your session tries to find the difference between its managed object graph and the underlying datastore and generate the appropriate SQL statements (updates, inserts, etc.).

    So, how is this different than cayenne? The biggest different comes in managing /new/ objects. There isn't a lot of difference in managing /existing/ database objects (except that I run into more problems faulting relationships, see below). Expanding the "//do some work" line above, consider the following scenarios:

    A a = new A();
    B b = new B();
    b.setA(a);//no exception here...
    //IF: the relationship from B to A specifies cascade="save-update" (or equivalent):
    //THEN: At least two insert statements generated at this point, one for a (first), then one for b.
    //IF: the cascade isn't set
    //THEN: this line will result in an exception b/c A isn't committed.
    sess.save(b);

    A a = new A();
    B b = new B();
    sess.save(b);
    tx.commit();

    B will be saved. A will be gc'ed.

    Suppose we now have a saved B instance.

    B b = getBFromSomewhere();

    b.setSomeProperty("C");//no sql yet
    b.setSomeProperty2("B");//no sql yet
    b.setA(new A());// no sql yet. cascade="save-update" and the flush will be ok (A SQL generated); with no cascade, we'll get an exception during the flush.
    sess.flush();//UPDATE sql event generated.
    tx.commit();//commit to the database. Note that the distinction between flush and commit really only matters on databases that support true transactions.

    It's worth noting that in most of the code that I write on a daily basis, the boiler-plate code is abstracted away and I never deal with it, dealing instead with DAO objects that hide all of the session and transactions.
    I'm personally less likely to use a DAO in my cayenne code because the ObjectContext is generally a simpler paradigm, at least for me. It's fairly simple to think of it as an in-memory transaction, that validates your objects (at commitChanges()) before generating /any/ SQL. :)

    RE Lazy Fetching
    If I have the concept correct, this is another term for what EOF calls "faulting" behavior. IMO optimized/smart faulting behavior is the single most important reason to use an ORM. The conceptual differences between a RDBMS and an OO language can result in massive problems with a macro design, one that a good ORM solves via intelligent faulting algorithms. I had just assumed that this was a "moot" issue based on the fundamental solutions offered by EOF. Are there any essential differences in features of "Lazy Fetching" that you can point out?
    Yes. Lazy Fetching in hibernate is... time sensitive. You cannot fault a relationship if the session that loaded the parent object has been closed in the meantime. You cannot fault a relationship in the middle of a lifecycle/event listener (pre/post update/save/delete, etc.). Doing so will result in the dreaded LazyInitializationException. :) Hibernate uses proxies in places of Cayenne's "fault" objects. So you get a collection with a list of proxies rather than a collection with a list of faults. In theory, it's the same idea. In practice, there's a big difference. Namely that you can easily tell, in cayenne, if you're dealing with a fault vs. an "inflated" object. More appropriately, you never actually access the fault. By the time your code access an object, the faulting has occurred. Hibernate defers faulting until you call a method on a proxy. It seems like a smart idea (don't fault the object unless you really, really, /really/ need it), but the problem is "value replacement" and equivalence. Let me give an example, based on the above code about sessions:

    Suppose we have b:

    B b = getBFromSomewhere();


    B has a relationship to A. In cayenne-world, that means that the underlying property, a, in object b, contains a fault. In the Hibernate world, the underlying property, a, in object b, contains a proxy, we'll call it a'. So for, no real difference.

    A a = b.getA();//Cayenne resolves the fault here, hibernate does NOT!

    So in Cayenne, at this point, a is really a. In Hibernate, a is still a proxy, ie, a is a'.

    a.getSomeValue();//hibernate faults here; cayenne is already faulted.

    So now a in cayenne is still a. And a in hibernate is STILL a proxy (a')! Because hibernate can't replace the proxy reference a (a'), with the "real" value of a. So instead, it replaces the /internal/ "fault" object (niternal to the proxy) with the real a, and calls getSomeValue on it, and returns it. As I mentioned before, this is /usually/ fine, but there is a distinct issue with inheritance doing things the Hibernate way, which is when C extends A, and a is, in fact, an instance of C. The proxy will ONLY be an instanceof A, even though comparisons to the class (a.getClass()) will return the class object from the underlying object (an instance of C), so you get the retarded behavior I mentioned in my first e-mail, where checking, eg, C.class.isInstance(a) fails.
    RE dbentity/objentity differences

    Is the reason associated with the maturity of the "faulting" behavior (or something else)?
    I'm not sure, really. I think it's more a difference in philosophy. I have not interacted much on the hibernate mailing list. I've read a lot of hibernate source code and comments (during various debugging sessions) and I've read a lot of mailing list discussions trying to find answers to problems, but I've never interacted directly with the developers of hibernate. That said, my impression of the philosophy and attitude is that "ORM is about the object layer. Leave the db stuff to us. Really. Trust us." :)
    RE Google "hibernate lazyinitializationexception" to see what I mean.

    OK, I googled it as you suggested, and found a few (what I call dissertations) on the subject that suggest that Hibernate does not have a cogent "faulting" design, and that the Hibernate-Session is not as mature a model for transactions as is Cayenne's ObjectContext (if I understand the issues). Is this correct?

    Correct me if I am wrong (please :) ), but it is starting to sound similar to the discussions of C++ garbage collection vs Java garbage collection (i.e. C++ doesn't really embrace garbage collection as a problem that should be handled by anyone but the programmer)
    That's how I would call it.
    This is a rather insightful thread (note that Gavin is the lead hibernate developer). It's from 2003, but the philosophy/mindset arguably still exists in the hibernate project and its apis:

    https://forums.hibernate.org/viewtopic.php?f=1&t=42&start=0

    In particular, there's this post by Gavin:

    "NO!! This is very evil functionality! It is essential to the performance and transaction isolation characteristics of Hibernate that the beginning and end of a session (ie. a connection to the database) is demarcated by the developer!

    An auto-reconnect feature might look superficially appealing but it will reult in a system that performs like a dog and has doubtful transaction semantics."

    And basically, that's it in a nutshell. The thread is discussing fetching a lazy relationship after the session has closed. If that were the /only/ "fringe case" of lazy relationship navigation in hibernate, it would probably be tolerable. But it turns out, it's /not/ the only fringe case. I constantly encounter what I would call "rough edges" around Hibernate's lazy fetching.

    HTH,

    Robert
    Thanks again for your input,
    Joe













    On Sep 6, 2010, at 11:06 AM, Robert Zeigler wrote:

    Hi Joe,

    First, this e-mail wound up a lot longer than I intended, apologies! The short version is: having used both a fair bit, I prefer cayenne, but they both have strengths and weaknesses. Most of this e-mail details what I view as weaknesses in Hibernate. :)

    On to the long version!

    I still know cayenne better than hibernate, but I've used both extensively (2+ years of experience with hibernate, on a fairly large system with > 80 tables; I've used cayenne for > 5 years now). I don't have time right now to put together a systematic comparison, but here are a few notes:

    Hibernate: POJO - some people love it, some hate it. I'm in the latter camp. You lose out on a lot of code-reuse, debugging is more difficult, and it necessitates constructs like hibernate proxies, which are a PITA to deal with, IMO.
    Cayenne: interface (inheritance, in practice)-based design. Some people don't like the domain-structure constraints it imposes. I find it makes debugging easier and results in more code re-use. And, no proxies. Objects are what they are. More importantly, objects are what you think they are (in hibernate-land, I've had code like the following:

    public class MyObject2 extends MyObject1 {...}

    elsewhere:

    MyObject1 someobj = someCodeThatReturnsMyObject1();
    if (MyObject2.class.isInstance(someobj)) {
    ((MyObject2)someobj).callMyObject2Method();
    }

    And the above code will throw a cast class exception. Yup. That's right. Because someobj is a proxy. A call to getClass() returns the getClass() of the underlying object (an instance of MyObject2), but someobj, the proxy, technically only implements MyObject1. So you get a ClassCastException. Other variants include your code not executing at all, even when you know that someobj /should/ be an instance of MyObject2. The code above is, of course, contrived, but I've hit this in numerous "real world" scenarios.

    Hibernate & Cayenne both support "lazy fetching" in some form, but Cayenne's support is far superior, IMO (with bonafide faulting, etc.). This is a function, I think, of having supported it far longer (this was initially the reason that I used Cayenne rather than Hibernate). Google "hibernate lazyinitializationexception" to see what I mean. In particular, if you go the hibernate route, be very /very/ careful what you do in event listeners (pre/post commit, etc.) because it's very easy to hit exceptions there. Basically, I find that in Hibernate, event listeners are just barely better than useless. A great idea, but you can't really /do/ anything useful in them. And even the 3rd party modules, written by long-time hibernate developers, hit these edge cases (eg: hibernate envers for entity auditing/logging has had issues reported where they hit issues with lazyinitializationexception from using lifecycle listeners). The hibernate "way" was originally to not support lazy fetching at all; either all of the data you needed came into the request/session at once, or it wasn't there at all. This probably resulted in more /performant/ code (fewer queriest/hits to the db, for instance), but is basically not feasible in the world of 3rd party modules/integration/development: it's not always possible to know exactly what information you need at the beginning of, eg, a web request.

    I have to give kudos to the hibernate team for the extremely flexible mappings they support. I find cayenne mapping more /intuitive/ (thanks in part to the modeler), but there are edge mapping cases that are supported in hibernate that are not, to the best of my knowledge, supported in cayenne (cayenne 3.0 improves this discrepancy, though). As an example, hibernate supports more inheritance modeling schemes (table per concrete subclass, table per class, single table) than does cayenne, although cayenne 3.0 has improved in this regard. For simple mapping, hibernate may even be more straightforward than cayenne due to it's ability to analyze your domain objects and figure out the appropriate tables, etc. to create. On the other hand, I personally shy away from having hibernate auto-create my table structure. I find it results in less thinking about what's really occurring at the db level. Although that is, to a greater or lesser extent, the point of an ORM system, it's my opinion that it's still important to think about how the data is physically mapped at the db level. (I should note that you can specify the exact mapping characteristics in hibernate. But my observation is that the tendency is to let hibernate "do it's thing" until you find a problem with the way it did it's thing, and you tell hibernate the "right way" to do it).

    Metadata: There's no "dbentity" vs. "objentity" separation. That's great for some people... but really too bad. :) My personal experience is that cayenne's meta-data support is more accessible and richer than Hibernate's, but that's probably a function, at least in part, of familiarity with the frameworks.

    pks: Cayenne's approach is: "these are a database-artifact and shouldn't pollute your data model, unless you need them to be there". Hibernate's approach is: "pk's are an integral part of your domain object" (for the most part).

    ObjectContext vs. Session. Session is a poor man's ObjectContext. ;) That's an opinion, of course. But. On the surface, these two objects do similar sorts of things: save, commit transactions, etc. But in reality, they are completely different paradigms. In Cayenne, an ObjectContext is very much a "sandbox" where you can make changes, roll them back, commit them, etc. A hibernate session is more like a command queue: you instruct it to update, save, or delete specific objects, ask it for "Criteria" for criteria-based queries, etc. They may sound similar but there's a big difference in how you use them. Basically, hibernate doesn't have the notion of "modified or new object that needs to be saved at some point in the future, but which I should retain a reference to now." :) In cayenne, you can do something like this:

    void someMethod(ObjectContext context) {
    context.newObject(SomePersistentObject.class).setSomeProperty("foo");
    ...
    }

    Now when that particular context is committed, a new instance of SomePersistentObject will be committed, without the calling code having to know about it. Arguably, this is a method witih "side effects" that should be avoided, but there are legitimate use cases for this. Consider a recent example I encountered. A hibernate project I work on manages a set of "projects". Changes to projects are audited, except when the project is first created/in state "project_created" (a custom flag, unrelated to hibernate). I recently needed to add support for one auditing operation: record the date of creation, and the user who created the project. WIthout getting into gory details, the simplest way to do this would have been to modify the service responsible for creating all project types, along the lines of this (how I would do this in cayenne):

    public <T extends Project> T createProject(Class<T> type) {
    T project = codeToCreateProject();
    Audit a = objectContext.newObject(Audit.class);
    a.setProject(project);
    a.setMessage("Project Created");
    a.setDate(new Date());
    return project;
    }

    Notes: the project creator is not (and cannot, due to design constraints) commit the project to the database at this point in the code. That's fine in cayenne: as long as the calling code is using the same object context (it always would be in my case), the Audit object would be committed at the same time the project is, and life would be happy. But the project is not cayenne. It is hibernate. So:

    public <T extends Project> T createProject(Class<T> type) {
    T project = codeToCreateProject();
    Audit a = new Audit();
    a.setProject(project);
    a.setMessage("Project Created");
    a.setDate(new Date());
    return project;
    }

    Except, what happens to a? The answer is: nothing. It isn't ever saved. It would be, if Project had a reverse relationship to audit (List<Audit> getAudits()), that was set to cascade the "save" and "update" operations.
    But Project didn't/doesn't, and I wasn't allowed to add it. There was no way to tell hibernate: "Look, I've got this object, and I wan't you to save it, but, not right this second". You can call: session.save(a). But that results in an immediate commit the audit object (and ONLY the audit object!), so if the project isn't yet persisted to the db, you get a relationship constraint violation, trying to save a relationship to an unsaved object. There's also a session.persist(a) method, part of EJB3 spec, which is theoretically like cayenne's "register", but in hibernate, its functionally equivalent (or very nearly so) to session.save(a): it triggers an immediate commit to the database (at least in our application setup). There is no equivalent to cayenne's "context.register(a)". I finally solved this issue via life cycle event listeners, and it was a pain (you have to be /extremely/ careful about what you do in hibernate event listeners. In particular, read operations that result in a hit to the database will cause you major grief, even if you don't modify anything, and modification of any kind is next to impossible).

    All that said, there are /some/ good ideas in hibernate. :) For one thing, Cayenne's /requirement/ that two objects with a shared relationship be in the same ObjectContext can cause grief, particularly in web applications. Imagine you have a form to create a new object of type Foo. Foo has a relationship to Bar. You may not want to register this object with the context until you know that the new Foo object is a "valid" object (lest you wind up with "dirty" objects polluting subsequent commits, using an ObjectContext-per-user session paradigm). But you can't do that: when you set the Bar relationship, Foo will be registered with the context. That's usually fine... you can usually rollback the changes... but it does mean sometimes having to think carefully about what "state" your objects are in.

    I've yet to find the "perfect" ORM. THere isn't one, as far as I'm concerned, b/c there's simply a mismatch between the db model and the object model that will result in tradeoffs. But I find Cayenne far easier to learn and use than Hibernate.

    Cheers,

    Robert
    On Sep 5, 2010, at 9/51:21 PM , Joe Baldwin wrote:

    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison. Before I "reinvent the wheel" so-to speak with a new evaluation, I would like to find out if anyone has done a recent and fair comparison/evaluation (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very easy decision. While Hibernate had been widely adopted (and was on a number of job listings), it seemed like the core decision was made mostly because "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough of the core ORM features that I needed, in addition to being very similar conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM implementations). Cayenne seems to support a more "agile" development model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven by "camps" of opinions on the best practices for accomplishing abstraction of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my understanding of the comparison.

    Thanks,
    Joe
  • Mike Kienenberger at Sep 6, 2010 at 6:20 pm

    On Mon, Sep 6, 2010 at 2:02 PM, Robert Zeigler wrote:

    RE ObjectContext vs Session
    I may be mixed up but it sounds like the ObjectContext is similar in
    concept to EOF. It sounds like you are saying that among other things the
    Hibernate-Session makes simple transactional tasks much more difficult and
    may even interfere with a Factory-Method approach to building data objects
    within a transaction.
    According to my (very limited) knowledge of EOF, ObjectContext is similar.
    :) Session is somewhat similar. This is from the Session api docs:

    A typical transaction should use the following idiom:

    Session sess = factory.openSession();
    Transaction tx;
    try {
    tx = sess.beginTransaction();
    //do some work
    ...
    tx.commit();
    }
    catch (Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
    }
    finally {
    sess.close();
    }

    So they are demonstrating the use of a transaction to perform multiple
    units of work. Of note, they don't mention here that you would normally
    either call: session.flush() (before tx.commit) or else your session would
    be set to "AUTO_FLUSH". Basically, that means that your session tries to
    find the difference between its managed object graph and the underlying
    datastore and generate the appropriate SQL statements (updates, inserts,
    etc.).
    I have not used Hibernate, but I have extensively used JPA which (I am told)
    is mostly based on Hibernate.

    One big difference between JPA and Cayenne is that there's no lightweight
    unit of work. I am not certain if this is also true of Hibernate, but I
    suspect it is.

    A unit of work in JPA (EntityManager -- I think it's equivalent to a
    Hibernate Session) is an open database transaction. If you want to have
    more than one, you have to open more connections to the database. This
    also means that you wouldn't want to maintain your unit of work
    (EntityManager) across web requests, since you might never come back to it,
    leaving the database connection open.

    Maybe someone who has used Hibernate can comment on that.

    It's probably also worth noting that in JPA calling rollback() only performs
    a database rollback. Your java application object graph remains unchanged,
    leaving your application state "undefined" -- JPA's terminology, not mine.
    I would have used "unusable" instead :-)

    Again, don't know if that's true for Hibernate as well.
  • Joe Baldwin at Sep 6, 2010 at 7:25 pm
    Robert,
    And basically, that's it in a nutshell. The thread is discussing fetching a lazy relationship after the session has closed. If that were the /only/ "fringe case" of lazy relationship navigation in hibernate, it would probably be tolerable. But it turns out, it's /not/ the only fringe case. I constantly encounter what I would call "rough edges" around Hibernate's lazy fetching.
    It took a bit to find a simple quote from the thread, but I think this is it:

    "The problem is in Hibernate's lazy loading: you can't load non-initialized objects after session is disconnected/closed."

    I am still a bit confused by the jargon, because I thought "hibernate session" was analogous to "DataContext". However, in this thread you referenced, it sounds like they are using it as if it were analogous to a "transaction" or maybe even a transient "database connection".

    Also, if I understand Gavin, (and as you point out) it sounds as if he does not embrace "faulting behavior" (aka lazy fetching) as part of the core responsibilities of an ORM.

    If I understand these comments, then I would have to disagree with their core ORM design pattern, because it is my opinion that intelligent-faulting behavior is one of the most important functions of an ORM. NeXT/Apple EOF (one of the first ORM implementations) included transparent faulting (very similar to Cayenne in behavior) well before Hibernate was even started.

    Again, if I understand the comments, the Hibernate faulting design sounds like a very primitive and naive implementation.

    Am I misunderstanding this (or being too harsh)?

    Thanks,
    Joe
  • Robert Zeigler at Sep 6, 2010 at 7:41 pm
    I don't think you're misunderstanding. Their implementation causes me (and countless others) constant headaches.
    HibernateSession is the closest thing in Hibernate to the Cayenne ObjectContext (DataContext). But they aren't perfectly aligned.
    A session is certainly closer in sensibilities to a (managed) transaction than the ObjectContext is, although not perfectly analogous to a transaction, either. A session /can/ be held across multiple requests, and may or may not have a transaction associated with it at the current time. But the general pattern is session-per-request by default (I think seam changes this to "session-per-conversation").

    Robert
    On Sep 6, 2010, at 9/62:24 PM , Joe Baldwin wrote:

    Robert,
    And basically, that's it in a nutshell. The thread is discussing fetching a lazy relationship after the session has closed. If that were the /only/ "fringe case" of lazy relationship navigation in hibernate, it would probably be tolerable. But it turns out, it's /not/ the only fringe case. I constantly encounter what I would call "rough edges" around Hibernate's lazy fetching.
    It took a bit to find a simple quote from the thread, but I think this is it:

    "The problem is in Hibernate's lazy loading: you can't load non-initialized objects after session is disconnected/closed."

    I am still a bit confused by the jargon, because I thought "hibernate session" was analogous to "DataContext". However, in this thread you referenced, it sounds like they are using it as if it were analogous to a "transaction" or maybe even a transient "database connection".

    Also, if I understand Gavin, (and as you point out) it sounds as if he does not embrace "faulting behavior" (aka lazy fetching) as part of the core responsibilities of an ORM.

    If I understand these comments, then I would have to disagree with their core ORM design pattern, because it is my opinion that intelligent-faulting behavior is one of the most important functions of an ORM. NeXT/Apple EOF (one of the first ORM implementations) included transparent faulting (very similar to Cayenne in behavior) well before Hibernate was even started.

    Again, if I understand the comments, the Hibernate faulting design sounds like a very primitive and naive implementation.

    Am I misunderstanding this (or being too harsh)?

    Thanks,
    Joe


  • Joe Baldwin at Sep 6, 2010 at 8:12 pm
    Robert,

    Thanks again for your insight (and mapping some of the technical terms).

    Just as a random test of current faulting behavior I googled more on Hibernate and found:

    http://bwinterberg.blogspot.com/2009/08/how-to-eagerly-fetch-associations-with.html

    It appears that the Gavin-lazy-fetch philosophy was not an oversight or legacy-anachronism (i.e. comparing new to old), it appears it is in fact an intentional and well considered design pattern.

    This *may* have something to do with their adoption of the "Session" design pattern vs the more traditional and mature "ObjectContext" pattern. I don't really know, but I disagree on a fundamental level with their approach.

    The more I think about this the more that the Cayenne vs Hibernate faulting-design differences mirror the C/C++ vs Java Memory Management evolution. Java aggressively addressed the "intelligent" Garbage Collection problem and assigned the responsibility to the JVM (which has evolved to the point at which the "best practice" for the programmer is "don't mess with it", while C++ still has not even officially recognized it as a problem.

    This faulting behavior appears to be a serious flaw in the Hibernate design, and one that is easily demonstrated as an advanced ORM feature of Cayenne. I agree that this almost reduces the concept of "relationships" to useless in Hibernate. How can Hibernate possibly get away with dismissing post-session lazyfetchexceptions as anything but a serious design flaw an one that should be handled by any version-1.0 ORM?

    Joe





    On Sep 6, 2010, at 3:41 PM, Robert Zeigler wrote:

    I don't think you're misunderstanding. Their implementation causes me (and countless others) constant headaches.
    HibernateSession is the closest thing in Hibernate to the Cayenne ObjectContext (DataContext). But they aren't perfectly aligned.
    A session is certainly closer in sensibilities to a (managed) transaction than the ObjectContext is, although not perfectly analogous to a transaction, either. A session /can/ be held across multiple requests, and may or may not have a transaction associated with it at the current time. But the general pattern is session-per-request by default (I think seam changes this to "session-per-conversation").

    Robert
    On Sep 6, 2010, at 9/62:24 PM , Joe Baldwin wrote:

    Robert,
    And basically, that's it in a nutshell. The thread is discussing fetching a lazy relationship after the session has closed. If that were the /only/ "fringe case" of lazy relationship navigation in hibernate, it would probably be tolerable. But it turns out, it's /not/ the only fringe case. I constantly encounter what I would call "rough edges" around Hibernate's lazy fetching.
    It took a bit to find a simple quote from the thread, but I think this is it:

    "The problem is in Hibernate's lazy loading: you can't load non-initialized objects after session is disconnected/closed."

    I am still a bit confused by the jargon, because I thought "hibernate session" was analogous to "DataContext". However, in this thread you referenced, it sounds like they are using it as if it were analogous to a "transaction" or maybe even a transient "database connection".

    Also, if I understand Gavin, (and as you point out) it sounds as if he does not embrace "faulting behavior" (aka lazy fetching) as part of the core responsibilities of an ORM.

    If I understand these comments, then I would have to disagree with their core ORM design pattern, because it is my opinion that intelligent-faulting behavior is one of the most important functions of an ORM. NeXT/Apple EOF (one of the first ORM implementations) included transparent faulting (very similar to Cayenne in behavior) well before Hibernate was even started.

    Again, if I understand the comments, the Hibernate faulting design sounds like a very primitive and naive implementation.

    Am I misunderstanding this (or being too harsh)?

    Thanks,
    Joe


  • Michael Gentry at Sep 6, 2010 at 7:59 pm
    The Hibernate Session is tied to a database connection. A Cayenne
    DataContext requests a connection from the DB connection pool when you
    commitChanges() or performQuery() and then releases it when done.
    Hibernate therefore has issues in a web application where you don't
    know how many request/response trips will be made from the browser to
    the application -- you can't really leave the database connection open
    indefinitely. Cayenne's DataContext transparently uses DB connections
    as needed and is more natural in this regard. Hibernate's proxied
    objects are also tied to their Session. This creates problems
    (faulting objects, updating and saving, etc) when the Session from one
    request/response was closed and then you try to use the objects in
    another request/response -- you have to re-attach objects to a
    Session. Cumbersome. Again, Cayenne does not have these problems.
    This issue was so bad in Hibernate that the Spring community created
    the Open Session In View filter and it still doesn't really solve the
    problems, but it does make it a little better.

    mrg

    On Mon, Sep 6, 2010 at 3:24 PM, Joe Baldwin wrote:
    Robert,
    And basically, that's it in a nutshell.  The thread is discussing fetching a lazy relationship after the session has closed.  If that were the /only/ "fringe case" of lazy relationship navigation in hibernate, it would probably be tolerable.  But it turns out, it's /not/ the only fringe case.  I constantly encounter what I would call "rough edges" around Hibernate's lazy fetching.
    It took a bit to find a simple quote from the thread, but I think this is it:

    "The problem is in Hibernate's lazy loading: you can't load non-initialized objects after session is disconnected/closed."

    I am still a bit confused by the jargon, because I thought "hibernate session" was analogous to "DataContext".  However, in this thread you referenced, it sounds like they are using it as if it were analogous to a "transaction" or maybe even a transient "database connection".

    Also, if I understand Gavin, (and as you point out) it sounds as if he does not embrace "faulting behavior" (aka lazy fetching) as part of the core responsibilities of an ORM.

    If I understand these comments, then I would have to disagree with their core ORM design pattern, because it is my opinion that intelligent-faulting behavior is one of the most important functions of an ORM.  NeXT/Apple EOF (one of the first ORM implementations) included transparent faulting (very similar to Cayenne in behavior) well before Hibernate was even started.

    Again, if I understand the comments, the Hibernate faulting design sounds like a very primitive and naive implementation.

    Am I misunderstanding this (or being too harsh)?

    Thanks,
    Joe



  • Joe Baldwin at Sep 6, 2010 at 8:32 pm
    Michael,

    Dude, you really have to start a cogent advertising campaign to promote Cayenne! These differences you point out (along with what I understand to be a deficiency in faulting behavior over the lifetime of a data object), are not insignificant. (I do believe that they are not widely understood however.)

    I was literally asked by a young project lead (in an aggressive tone) "why would you ever use anything other than Hibernate". This leads me to believe that they have not done their homework. I think that they could benefit from just the analysis share in today's emails.

    I personally think that Cayenne takes the best concepts from NeXT-EOF, and Java and have evolved them into a mature Enterprise-ready ORM (something I cannot say about the current version of Hibernate).

    While it would be great to have a book, and great to have an Entity Diagram integrator, I think a simple "Why Use Cayenne" white-paper or web-page that succinctly illustrates these differences would accomplish a lot. Developers have come to rely upon and *expect* intelligent garbage collection from Java (an arguably non-lanaguage related feature), why not be proactive about asserting core Cayenne features as core ORM features in the larger community?

    Joe



    On Sep 6, 2010, at 3:57 PM, Michael Gentry wrote:

    The Hibernate Session is tied to a database connection. A Cayenne
    DataContext requests a connection from the DB connection pool when you
    commitChanges() or performQuery() and then releases it when done.
    Hibernate therefore has issues in a web application where you don't
    know how many request/response trips will be made from the browser to
    the application -- you can't really leave the database connection open
    indefinitely. Cayenne's DataContext transparently uses DB connections
    as needed and is more natural in this regard. Hibernate's proxied
    objects are also tied to their Session. This creates problems
    (faulting objects, updating and saving, etc) when the Session from one
    request/response was closed and then you try to use the objects in
    another request/response -- you have to re-attach objects to a
    Session. Cumbersome. Again, Cayenne does not have these problems.
    This issue was so bad in Hibernate that the Spring community created
    the Open Session In View filter and it still doesn't really solve the
    problems, but it does make it a little better.

    mrg

    On Mon, Sep 6, 2010 at 3:24 PM, Joe Baldwin wrote:
    Robert,
    And basically, that's it in a nutshell. The thread is discussing fetching a lazy relationship after the session has closed. If that were the /only/ "fringe case" of lazy relationship navigation in hibernate, it would probably be tolerable. But it turns out, it's /not/ the only fringe case. I constantly encounter what I would call "rough edges" around Hibernate's lazy fetching.
    It took a bit to find a simple quote from the thread, but I think this is it:

    "The problem is in Hibernate's lazy loading: you can't load non-initialized objects after session is disconnected/closed."

    I am still a bit confused by the jargon, because I thought "hibernate session" was analogous to "DataContext". However, in this thread you referenced, it sounds like they are using it as if it were analogous to a "transaction" or maybe even a transient "database connection".

    Also, if I understand Gavin, (and as you point out) it sounds as if he does not embrace "faulting behavior" (aka lazy fetching) as part of the core responsibilities of an ORM.

    If I understand these comments, then I would have to disagree with their core ORM design pattern, because it is my opinion that intelligent-faulting behavior is one of the most important functions of an ORM. NeXT/Apple EOF (one of the first ORM implementations) included transparent faulting (very similar to Cayenne in behavior) well before Hibernate was even started.

    Again, if I understand the comments, the Hibernate faulting design sounds like a very primitive and naive implementation.

    Am I misunderstanding this (or being too harsh)?

    Thanks,
    Joe



  • Borut Bolčina at Sep 6, 2010 at 6:48 pm
    Hello Joe,

    I just recently began two projects based on Hibernate (and Tapestry 5), so I
    have limited knowledge to compare, but some of the differences immediately
    showed up:

    1.Code Life cycle
    If you have the luxury to start a project with no database schema, then in
    Hibernate you can start with POJOs, annotate them, create database on the
    fly (just by configuration) and make changes in code only. Another approach
    is to create an ER model (in MySQL Workbench for example), forward
    engineer/synchronize with the database and later create JAVA code with the
    Hibernate tools in Eclipse. But the tool is limited, you have to correct
    some output by hand. If you make lots of changes in the auto generated class
    and if you make changes in your favorite ER modelling tool and make changes
    to the database with this tool, then you have to re-generate java code at
    least a few times and than means you have to re-generate this code to some
    other package (I use com.acme.entities.generated) and make local merge of
    the old POJOs with the new ones. It doesn't consume much time, but with
    Cayenne you have auto-generated classes and subclasses where you put your
    business logic. I like the Cayenne approach, but I never got used to Cayenne
    modeler, since ot does not offer a graphical way of drawing or displaying db
    artifacts (ER model). If one prefers to start a fresh db design with his/her
    favorite ER modeling tool, then with Cayenne you reverse engineer the db
    schema with the modeler (the db engine must support constraints for
    relationships to appear in the modeler). When rev-engineered and not
    satisfied with the names of the relationship names (as was the case before
    smart naming strategy) you had to correct each one in the modeler and then
    (re)create the java classes. But since only the "auto" classes are
    (over)written no harm is done, except for the compiler errors which
    immediately show the location of offending method names. If one wants to
    have ER model, Cayenne model and the code itself in sync there is a lot of
    discipline to commit to. I think this is easier with Hibernate POJOs/Eclipse
    Hibernate Tools/ER modeler, at least you don't have to deal with two GUI
    tools. I would love to hear how other manage the life cycle - code/model
    modifications. I do not have much experience starting with an existing
    database - I guess I am the lucky one :-)

    2.ObjectContext versus Session
    This one was a really bad surprise when started with Hibernate. Object life
    cycle is much more natural with Cayenne. My first Lazyloading Exception
    emotion was: "What the hell am I doing wrong?". Then I realized that I can
    not follow the relationships if not eagerly fetched. _______ (insert some
    ugly word). A big plus for Cayenne here. I was told that Seam framework has
    solved the LazyLoadingException. Is this correct?

    3.POJO versus DataObject
    I haven't found a downside with my persistent objects inheriting from
    DataObjects. POJO hype?

    4.Bidirectional relationships
    Associations in Hibernate are not inherently bidirectional as are in
    Cayenne. According to Hibernate book this is considered a good thing. Quote:
    "POJO oriented persistence engines such as Hibernate don't implement managed
    associations. Contrary to EJB 2.0 CMR, Hibernate and JPA associations are
    all inherently unidirectional. As far as Hibernate is concerned, the
    association from Bid to Item is a different association then the association
    from Item to Bid! This is a good thing - otherwise your entity classes
    wouldn't be usable outside of a run time container.". I don't think this is
    a valid reason - you can use Cayenne in whatever environment you want and it
    manages the bidirectional relationships for you.

    5.Documentation
    Hibernate wins here totaly. Not only it gives confort to developers and
    managers, the book "Java persistence with Hibernate" really teaches you
    techniques and good practices. Also gives some recipes and anti-patterns.
    Cayenne will stay marginal if no book goes to print.

    6.Integration to other frameworks
    Hibernate wins here also. There are a number of frameworks which integrate
    with Hibernate, just google "hibernate integration". Where is my long
    awaited T5.2-Cayenne bridge? :-)

    These are just first observations I encountered during first two months of
    using Hibernate.

    Regards,
    Borut


    2010/9/5 Joe Baldwin <jfbaldwin@earthlink.net>
    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison.
    Before I "reinvent the wheel" so-to speak with a new evaluation, I would
    like to find out if anyone has done a recent and fair comparison/evaluation
    (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very
    easy decision. While Hibernate had been widely adopted (and was on a number
    of job listings), it seemed like the core decision was made mostly because
    "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough
    of the core ORM features that I needed, in addition to being very similar
    conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM
    implementations). Cayenne seems to support a more "agile" development
    model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven
    by "camps" of opinions on the best practices for accomplishing abstraction
    of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my
    understanding of the comparison.

    Thanks,
    Joe
  • Robert Zeigler at Sep 6, 2010 at 7:27 pm

    On Sep 6, 2010, at 9/61:47 PM , Borut Bolčina wrote:

    Hello Joe,

    I just recently began two projects based on Hibernate (and Tapestry 5), so I
    have limited knowledge to compare, but some of the differences immediately
    showed up:

    1.Code Life cycle
    If you have the luxury to start a project with no database schema, then in
    Hibernate you can start with POJOs, annotate them, create database on the
    fly (just by configuration) and make changes in code only. Another approach
    is to create an ER model (in MySQL Workbench for example), forward
    engineer/synchronize with the database and later create JAVA code with the
    Hibernate tools in Eclipse. But the tool is limited, you have to correct
    some output by hand. If you make lots of changes in the auto generated class
    and if you make changes in your favorite ER modelling tool and make changes
    to the database with this tool, then you have to re-generate java code at
    least a few times and than means you have to re-generate this code to some
    other package (I use com.acme.entities.generated) and make local merge of
    the old POJOs with the new ones. It doesn't consume much time, but with
    Cayenne you have auto-generated classes and subclasses where you put your
    business logic. I like the Cayenne approach, but I never got used to Cayenne
    modeler, since ot does not offer a graphical way of drawing or displaying db
    artifacts (ER model). If one prefers to start a fresh db design with his/her
    favorite ER modeling tool, then with Cayenne you reverse engineer the db
    schema with the modeler (the db engine must support constraints for
    relationships to appear in the modeler). When rev-engineered and not
    satisfied with the names of the relationship names (as was the case before
    smart naming strategy) you had to correct each one in the modeler and then
    (re)create the java classes. But since only the "auto" classes are
    (over)written no harm is done, except for the compiler errors which
    immediately show the location of offending method names. If one wants to
    have ER model, Cayenne model and the code itself in sync there is a lot of
    discipline to commit to. I think this is easier with Hibernate POJOs/Eclipse
    Hibernate Tools/ER modeler, at least you don't have to deal with two GUI
    tools. I would love to hear how other manage the life cycle - code/model
    modifications. I do not have much experience starting with an existing
    database - I guess I am the lucky one :-)
    :) Personal preference on this one, I guess. I've never much cared for ER diagrams. They're pretty, but I personally find the CayenneModeler's approach a faster way to work... usually. ;)

    2.ObjectContext versus Session
    This one was a really bad surprise when started with Hibernate. Object life
    cycle is much more natural with Cayenne. My first Lazyloading Exception
    emotion was: "What the hell am I doing wrong?". Then I realized that I can
    not follow the relationships if not eagerly fetched. _______ (insert some
    ugly word). A big plus for Cayenne here. I was told that Seam framework has
    solved the LazyLoadingException. Is this correct?
    I've heard it helps. Gavin is a committer on the Seam project, is he not? Still strikes me as odd that it requires an "application level framework" to cover up what is, IMO, an ORM-level hole. :)
    3.POJO versus DataObject
    I haven't found a downside with my persistent objects inheriting from
    DataObjects. POJO hype?
    Definitely agree.
    4.Bidirectional relationships
    Associations in Hibernate are not inherently bidirectional as are in
    Cayenne. According to Hibernate book this is considered a good thing. Quote:
    "POJO oriented persistence engines such as Hibernate don't implement managed
    associations. Contrary to EJB 2.0 CMR, Hibernate and JPA associations are
    all inherently unidirectional. As far as Hibernate is concerned, the
    association from Bid to Item is a different association then the association
    from Item to Bid! This is a good thing - otherwise your entity classes
    wouldn't be usable outside of a run time container.". I don't think this is
    a valid reason - you can use Cayenne in whatever environment you want and it
    manages the bidirectional relationships for you.
    To be fair, you /can/ make bi-directional properties. But it's the difference in defaults: Cayenne defaults to bi-directional; hibernate to unidirectional, and it requires much more work in hibernate to make the properties bi-directional. To make them "unidirectional" in cayenne requires deleting the corresponding property/mapping. ;)
    5.Documentation
    Hibernate wins here totaly. Not only it gives confort to developers and
    managers, the book "Java persistence with Hibernate" really teaches you
    techniques and good practices. Also gives some recipes and anti-patterns.
    Cayenne will stay marginal if no book goes to print.
    I confess, I don't have Java persistence with Hibernate (I should probably buy it, but I can't bring myself to contribute $$ to the hibernate ecosystem ;). The hibernate online docs are, in a sense, more complete than the cayenne docs. But the cayenne docs are, to me, at least, more /informative/.
    Also, I find cayenne much more /intuitive/. So, whereas I'm constantly frustrated with the hibernate online documentation, I haven't felt that way toward cayenne. ;) But that's an individual thing, and YMMV. Certainly, there are books for Hibernate, at once a consequence and cause of its success.
    6.Integration to other frameworks
    Hibernate wins here also. There are a number of frameworks which integrate
    with Hibernate, just google "hibernate integration". Where is my long
    awaited T5.2-Cayenne bridge? :-)
    Check out the trunk source? It's compatible with T5.2. At least, I have projects that are running with T5.2 and the latest t5cayenne source. :) Sorry, I've been crazy busy lately and haven't had time to put together a real release. But the code has made some nice progress in the last 6 weeks or so, including T5.2 compatibility and improved ValueEncoder support (trunk adds support for multi-key PK's. Take that, tapestry-hibernate! ;). I'm also planning on either updating the EntityField, or creating an alternative component (and deprecating EntityField) that works better. I have a working prototype of said new component in a personal project I'm working on, but it still has a couple of quirks that I need to fix before moving it directly into T5cayenne.

    Robert

    These are just first observations I encountered during first two months of
    using Hibernate.

    Regards,
    Borut


    2010/9/5 Joe Baldwin <jfbaldwin@earthlink.net>
    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison.
    Before I "reinvent the wheel" so-to speak with a new evaluation, I would
    like to find out if anyone has done a recent and fair comparison/evaluation
    (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very
    easy decision. While Hibernate had been widely adopted (and was on a number
    of job listings), it seemed like the core decision was made mostly because
    "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough
    of the core ORM features that I needed, in addition to being very similar
    conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM
    implementations). Cayenne seems to support a more "agile" development
    model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven
    by "camps" of opinions on the best practices for accomplishing abstraction
    of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my
    understanding of the comparison.

    Thanks,
    Joe
  • Borut Bolčina at Sep 6, 2010 at 8:11 pm
    2010/9/6 Robert Zeigler <robert.zeigler@roxanemy.com>
    On Sep 6, 2010, at 9/61:47 PM , Borut Bolčina wrote:

    Hello Joe,

    I just recently began two projects based on Hibernate (and Tapestry 5), so I
    have limited knowledge to compare, but some of the differences
    immediately
    showed up:

    1.Code Life cycle
    If you have the luxury to start a project with no database schema, then in
    Hibernate you can start with POJOs, annotate them, create database on the
    fly (just by configuration) and make changes in code only. Another approach
    is to create an ER model (in MySQL Workbench for example), forward
    engineer/synchronize with the database and later create JAVA code with the
    Hibernate tools in Eclipse. But the tool is limited, you have to correct
    some output by hand. If you make lots of changes in the auto generated class
    and if you make changes in your favorite ER modelling tool and make changes
    to the database with this tool, then you have to re-generate java code at
    least a few times and than means you have to re-generate this code to some
    other package (I use com.acme.entities.generated) and make local merge of
    the old POJOs with the new ones. It doesn't consume much time, but with
    Cayenne you have auto-generated classes and subclasses where you put your
    business logic. I like the Cayenne approach, but I never got used to Cayenne
    modeler, since ot does not offer a graphical way of drawing or displaying db
    artifacts (ER model). If one prefers to start a fresh db design with his/her
    favorite ER modeling tool, then with Cayenne you reverse engineer the db
    schema with the modeler (the db engine must support constraints for
    relationships to appear in the modeler). When rev-engineered and not
    satisfied with the names of the relationship names (as was the case before
    smart naming strategy) you had to correct each one in the modeler and then
    (re)create the java classes. But since only the "auto" classes are
    (over)written no harm is done, except for the compiler errors which
    immediately show the location of offending method names. If one wants to
    have ER model, Cayenne model and the code itself in sync there is a lot of
    discipline to commit to. I think this is easier with Hibernate
    POJOs/Eclipse
    Hibernate Tools/ER modeler, at least you don't have to deal with two GUI
    tools. I would love to hear how other manage the life cycle - code/model
    modifications. I do not have much experience starting with an existing
    database - I guess I am the lucky one :-)
    :) Personal preference on this one, I guess. I've never much cared for ER
    diagrams. They're pretty, but I personally find the CayenneModeler's
    approach a faster way to work... usually. ;)
    Yes indeed. I always like to keep my ER diagrams at my eye-level at the
    desktop where I work, just for the reference when someone walks by and asks
    where is that data stored. And it looks nice besides my other weird posters
    :-)
    Seriously - working with more then 5 tables really helps me understand the
    data relationships and I think ER diagrams are very much standard as long as
    RDMS will be around.

    2.ObjectContext versus Session
    This one was a really bad surprise when started with Hibernate. Object life
    cycle is much more natural with Cayenne. My first Lazyloading Exception
    emotion was: "What the hell am I doing wrong?". Then I realized that I can
    not follow the relationships if not eagerly fetched. _______ (insert some
    ugly word). A big plus for Cayenne here. I was told that Seam framework has
    solved the LazyLoadingException. Is this correct?
    I've heard it helps. Gavin is a committer on the Seam project, is he not?
    Still strikes me as odd that it requires an "application level framework" to
    cover up what is, IMO, an ORM-level hole. :)
    If this is true, yes, it is odd.

    3.POJO versus DataObject
    I haven't found a downside with my persistent objects inheriting from
    DataObjects. POJO hype?
    Definitely agree.
    4.Bidirectional relationships
    Associations in Hibernate are not inherently bidirectional as are in
    Cayenne. According to Hibernate book this is considered a good thing. Quote:
    "POJO oriented persistence engines such as Hibernate don't implement managed
    associations. Contrary to EJB 2.0 CMR, Hibernate and JPA associations are
    all inherently unidirectional. As far as Hibernate is concerned, the
    association from Bid to Item is a different association then the
    association
    from Item to Bid! This is a good thing - otherwise your entity classes
    wouldn't be usable outside of a run time container.". I don't think this is
    a valid reason - you can use Cayenne in whatever environment you want and it
    manages the bidirectional relationships for you.
    To be fair, you /can/ make bi-directional properties. But it's the
    difference in defaults: Cayenne defaults to bi-directional; hibernate to
    unidirectional, and it requires much more work in hibernate to make the
    properties bi-directional. To make them "unidirectional" in cayenne requires
    deleting the corresponding property/mapping. ;)
    Not so much work to make them bidirectional, but using them requires a
    utility method to be written for each bi-directional association so one does
    not forget to set the other site. It feels me uncomfortable. Take a look at
    this:
    http://stackoverflow.com/questions/3528595/hibernate-link-table-with-additional-columns-saving-in-one-transaction
    Any comments from Cayenne perspective?

    What also bothers me is this @Cascade annotation which must be set on the
    getters to save the parts of object graph you want to if you don't want to
    have many lines of code.

    5.Documentation
    Hibernate wins here totaly. Not only it gives confort to developers and
    managers, the book "Java persistence with Hibernate" really teaches you
    techniques and good practices. Also gives some recipes and anti-patterns.
    Cayenne will stay marginal if no book goes to print.
    I confess, I don't have Java persistence with Hibernate (I should probably
    buy it, but I can't bring myself to contribute $$ to the hibernate ecosystem
    ;). The hibernate online docs are, in a sense, more complete than the
    cayenne docs. But the cayenne docs are, to me, at least, more
    /informative/.
    Also, I find cayenne much more /intuitive/. So, whereas I'm constantly
    frustrated with the hibernate online documentation, I haven't felt that way
    toward cayenne. ;) But that's an individual thing, and YMMV. Certainly,
    there are books for Hibernate, at once a consequence and cause of its
    success.
    Cayenne's documentation lacked (lacks) info on Caching and everyday
    practices.

    6.Integration to other frameworks
    Hibernate wins here also. There are a number of frameworks which integrate
    with Hibernate, just google "hibernate integration". Where is my long
    awaited T5.2-Cayenne bridge? :-)
    Check out the trunk source? It's compatible with T5.2. At least, I have
    projects that are running with T5.2 and the latest t5cayenne source. :)
    Sorry, I've been crazy busy lately and haven't had time to put together a
    real release. But the code has made some nice progress in the last 6 weeks
    or so, including T5.2 compatibility and improved ValueEncoder support (trunk
    adds support for multi-key PK's. Take that, tapestry-hibernate! ;). I'm
    also planning on either updating the EntityField, or creating an alternative
    component (and deprecating EntityField) that works better. I have a working
    prototype of said new component in a personal project I'm working on, but it
    still has a couple of quirks that I need to fix before moving it directly
    into T5cayenne.
    Glad to hear that. But you are like those RAF's Tornado airplanes, they fly
    well bellow the radar :-)

    -Borut


    Robert

    These are just first observations I encountered during first two months of
    using Hibernate.

    Regards,
    Borut


    2010/9/5 Joe Baldwin <jfbaldwin@earthlink.net>
    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate
    Comparison.
    Before I "reinvent the wheel" so-to speak with a new evaluation, I would
    like to find out if anyone has done a recent and fair
    comparison/evaluation
    (and has published it).

    When I initially performed my evaluation of the two, it seemed like a
    very
    easy decision. While Hibernate had been widely adopted (and was on a
    number
    of job listings), it seemed like the core decision was made mostly
    because
    "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported
    enough
    of the core ORM features that I needed, in addition to being very
    similar
    conceptually to NeXT EOF (which was the first stable Enterprise-ready
    ORM
    implementations). Cayenne seems to support a more "agile" development
    model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be
    driven
    by "camps" of opinions on the best practices for accomplishing
    abstraction
    of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update
    my
    understanding of the comparison.

    Thanks,
    Joe
  • Borut Bolčina at Sep 29, 2010 at 1:40 pm
    Hi Robert (and others),

    I am starting one fresh project and wanted to test-drive t5cayenne. For
    trunk sources to compile you have to add

    <repository>
    <id>caucho</id>
    <url>http://caucho.com/m2</url>
    </repository>

    in the parent POM. Now lets take this baby for a spin :-)

    -Borut

    2010/9/6 Robert Zeigler <robert.zeigler@roxanemy.com>
    Check out the trunk source? It's compatible with T5.2. At least, I have
    projects that are running with T5.2 and the latest t5cayenne source. :)
    Sorry, I've been crazy busy lately and haven't had time to put together a
    real release. But the code has made some nice progress in the last 6 weeks
    or so, including T5.2 compatibility and improved ValueEncoder support (trunk
    adds support for multi-key PK's. Take that, tapestry-hibernate! ;). I'm
    also planning on either updating the EntityField, or creating an alternative
    component (and deprecating EntityField) that works better. I have a working
    prototype of said new component in a personal project I'm working on, but it
    still has a couple of quirks that I need to fix before moving it directly
    into T5cayenne.

    Robert
  • Robert Zeigler at Sep 29, 2010 at 1:47 pm
    Hm. Strange.. I work on it frequently, and compile it fine w/out that dependency?

    I'll check into this.

    Robert
    On Sep 29, 2010, at 9/298:39 AM , Borut Bolčina wrote:

    Hi Robert (and others),

    I am starting one fresh project and wanted to test-drive t5cayenne. For
    trunk sources to compile you have to add

    <repository>
    <id>caucho</id>
    <url>http://caucho.com/m2</url>
    </repository>

    in the parent POM. Now lets take this baby for a spin :-)

    -Borut

    2010/9/6 Robert Zeigler <robert.zeigler@roxanemy.com>
    Check out the trunk source? It's compatible with T5.2. At least, I have
    projects that are running with T5.2 and the latest t5cayenne source. :)
    Sorry, I've been crazy busy lately and haven't had time to put together a
    real release. But the code has made some nice progress in the last 6 weeks
    or so, including T5.2 compatibility and improved ValueEncoder support (trunk
    adds support for multi-key PK's. Take that, tapestry-hibernate! ;). I'm
    also planning on either updating the EntityField, or creating an alternative
    component (and deprecating EntityField) that works better. I have a working
    prototype of said new component in a personal project I'm working on, but it
    still has a couple of quirks that I need to fix before moving it directly
    into T5cayenne.

    Robert
  • Borut Bolčina at Sep 29, 2010 at 1:59 pm
    This is what I got, but mind I am behind company nexus - I'll try at home
    with clean local repo.


    Missing:
    ----------
    1) com.caucho:resin-hessian:jar:3.1.6

    Try downloading the file manually from the project website.

    Then, install it using the command:
    mvn install:install-file -DgroupId=com.caucho
    -DartifactId=resin-hessian -Dversion=3.1.6 -Dpackaging=jar
    -Dfile=/path/to/fil
    e

    Alternatively, if you host your own repository you can deploy the file
    there:
    mvn deploy:deploy-file -DgroupId=com.caucho -DartifactId=resin-hessian
    -Dversion=3.1.6 -Dpackaging=jar -Dfile=/path/to/file
    -Durl=[url] -DrepositoryId=[id]

    Path to dependency:
    1)
    com.googlecode.tapestry5-cayenne:tapestry5-cayenne-client:jar:0.3-SNAPSHOT
    2) org.apache.cayenne:cayenne-client:jar:3.0
    3) com.caucho:resin-hessian:jar:3.1.6

    ----------
    1 required artifact is missing.

    for artifact:
    com.googlecode.tapestry5-cayenne:tapestry5-cayenne-client:jar:0.3-SNAPSHOT

    from the specified remote repositories:
    apache.snapshots (http://people.apache.org/repo/m2-snapshot-repository),
    central (https://nexus.interseek.com/content/groups/releases),
    tapestry-snapshots (http://tapestry.formos.com/maven-snapshot-repository/
    ),
    tapestry-pending-releases (
    http://people.apache.org/~hlship/tapestry-ibiblio-rsynch-repository/),
    cayenne.deps (http://objectstyle.org/maven2)



    Best,
    Borut


    2010/9/29 Robert Zeigler <robert.zeigler@roxanemy.com>
    Hm. Strange.. I work on it frequently, and compile it fine w/out that
    dependency?

    I'll check into this.

    Robert
    On Sep 29, 2010, at 9/298:39 AM , Borut Bolčina wrote:

    Hi Robert (and others),

    I am starting one fresh project and wanted to test-drive t5cayenne. For
    trunk sources to compile you have to add

    <repository>
    <id>caucho</id>
    <url>http://caucho.com/m2</url>
    </repository>

    in the parent POM. Now lets take this baby for a spin :-)

    -Borut

    2010/9/6 Robert Zeigler <robert.zeigler@roxanemy.com>
    Check out the trunk source? It's compatible with T5.2. At least, I have
    projects that are running with T5.2 and the latest t5cayenne source. :)
    Sorry, I've been crazy busy lately and haven't had time to put together
    a
    real release. But the code has made some nice progress in the last 6
    weeks
    or so, including T5.2 compatibility and improved ValueEncoder support
    (trunk
    adds support for multi-key PK's. Take that, tapestry-hibernate! ;). I'm
    also planning on either updating the EntityField, or creating an
    alternative
    component (and deprecating EntityField) that works better. I have a
    working
    prototype of said new component in a personal project I'm working on,
    but it
    still has a couple of quirks that I need to fix before moving it
    directly
    into T5cayenne.

    Robert
  • Robert Zeigler at Sep 29, 2010 at 4:25 pm
    Ok, so, t5c doesn't depend on resin-hessian directly; cayenne-rop does. Since I've done cayenne dev work, I already had the dependency. Are you using tapestry-cayenne-server, or tapestry-cayenne-client?
    server shouldn't need the dependency at all; if it's complaining about it, let me know and I'll dig a little more.

    Robert
    On Sep 29, 2010, at 9/298:59 AM , Borut Bolčina wrote:

    This is what I got, but mind I am behind company nexus - I'll try at home
    with clean local repo.


    Missing:
    ----------
    1) com.caucho:resin-hessian:jar:3.1.6

    Try downloading the file manually from the project website.

    Then, install it using the command:
    mvn install:install-file -DgroupId=com.caucho
    -DartifactId=resin-hessian -Dversion=3.1.6 -Dpackaging=jar
    -Dfile=/path/to/fil
    e

    Alternatively, if you host your own repository you can deploy the file
    there:
    mvn deploy:deploy-file -DgroupId=com.caucho -DartifactId=resin-hessian
    -Dversion=3.1.6 -Dpackaging=jar -Dfile=/path/to/file
    -Durl=[url] -DrepositoryId=[id]

    Path to dependency:
    1)
    com.googlecode.tapestry5-cayenne:tapestry5-cayenne-client:jar:0.3-SNAPSHOT
    2) org.apache.cayenne:cayenne-client:jar:3.0
    3) com.caucho:resin-hessian:jar:3.1.6

    ----------
    1 required artifact is missing.

    for artifact:
    com.googlecode.tapestry5-cayenne:tapestry5-cayenne-client:jar:0.3-SNAPSHOT

    from the specified remote repositories:
    apache.snapshots (http://people.apache.org/repo/m2-snapshot-repository),
    central (https://nexus.interseek.com/content/groups/releases),
    tapestry-snapshots (http://tapestry.formos.com/maven-snapshot-repository/
    ),
    tapestry-pending-releases (
    http://people.apache.org/~hlship/tapestry-ibiblio-rsynch-repository/),
    cayenne.deps (http://objectstyle.org/maven2)



    Best,
    Borut


    2010/9/29 Robert Zeigler <robert.zeigler@roxanemy.com>
    Hm. Strange.. I work on it frequently, and compile it fine w/out that
    dependency?

    I'll check into this.

    Robert
    On Sep 29, 2010, at 9/298:39 AM , Borut Bolčina wrote:

    Hi Robert (and others),

    I am starting one fresh project and wanted to test-drive t5cayenne. For
    trunk sources to compile you have to add

    <repository>
    <id>caucho</id>
    <url>http://caucho.com/m2</url>
    </repository>

    in the parent POM. Now lets take this baby for a spin :-)

    -Borut

    2010/9/6 Robert Zeigler <robert.zeigler@roxanemy.com>
    Check out the trunk source? It's compatible with T5.2. At least, I have
    projects that are running with T5.2 and the latest t5cayenne source. :)
    Sorry, I've been crazy busy lately and haven't had time to put together
    a
    real release. But the code has made some nice progress in the last 6
    weeks
    or so, including T5.2 compatibility and improved ValueEncoder support
    (trunk
    adds support for multi-key PK's. Take that, tapestry-hibernate! ;). I'm
    also planning on either updating the EntityField, or creating an
    alternative
    component (and deprecating EntityField) that works better. I have a
    working
    prototype of said new component in a personal project I'm working on,
    but it
    still has a couple of quirks that I need to fix before moving it
    directly
    into T5cayenne.

    Robert
  • Mike Kienenberger at Sep 29, 2010 at 4:33 pm
    Let me recommend a new thread with a more appropriate subject.

    I doubt many people expect questions about t5cayenne in a thread about
    Hibernate.
    On Wed, Sep 29, 2010 at 9:39 AM, Borut Bolčina wrote:
    Hi Robert (and others),

    I am starting one fresh project and wanted to test-drive t5cayenne. For
    trunk sources to compile you have to add

    <repository>
    <id>caucho</id>
    <url>http://caucho.com/m2</url>
    </repository>

    in the parent POM. Now lets take this baby for a spin :-)

    -Borut

    2010/9/6 Robert Zeigler <robert.zeigler@roxanemy.com>
    Check out the trunk source? It's compatible with T5.2.  At least, I have
    projects that are running with T5.2 and the latest t5cayenne source. :)
    Sorry, I've been crazy busy lately and haven't had time to put together a
    real release.  But the code has made some nice progress in the last 6 weeks
    or so, including T5.2 compatibility and improved ValueEncoder support (trunk
    adds support for multi-key PK's. Take that, tapestry-hibernate! ;).  I'm
    also planning on either updating the EntityField, or creating an alternative
    component (and deprecating EntityField) that works better.  I have a working
    prototype of said new component in a personal project I'm working on, but it
    still has a couple of quirks that I need to fix before moving it directly
    into T5cayenne.

    Robert
  • Robert Zeigler at Sep 29, 2010 at 5:22 pm
    Indeed.... I think Borut continued from the old thread with a mind to post his observations on cayenne vs. hibernate, eg, integration with tapestry5, ease of development, etc. with his new project, latest code, etc. Those observations would be appropriate under the existing thread and existing subject... but you're right that discussions of how to build t5c from source are irrelevant. I'll add a bit of relevance: one (current) difference between integrating cayenne with T5.2 via the tapestry5-cayenne library vs. integrating hibernate with T5.2 is that the tapestry-hibernate module is built for you/available as a maven artifact, whereas you currently have to build t5c from source to be T5.2 compatible. ;)

    Robert
    On Sep 29, 2010, at 9/2911:33 AM , Mike Kienenberger wrote:

    Let me recommend a new thread with a more appropriate subject.

    I doubt many people expect questions about t5cayenne in a thread about
    Hibernate.
    On Wed, Sep 29, 2010 at 9:39 AM, Borut Bolčina wrote:
    Hi Robert (and others),

    I am starting one fresh project and wanted to test-drive t5cayenne. For
    trunk sources to compile you have to add

    <repository>
    <id>caucho</id>
    <url>http://caucho.com/m2</url>
    </repository>

    in the parent POM. Now lets take this baby for a spin :-)

    -Borut

    2010/9/6 Robert Zeigler <robert.zeigler@roxanemy.com>
    Check out the trunk source? It's compatible with T5.2. At least, I have
    projects that are running with T5.2 and the latest t5cayenne source. :)
    Sorry, I've been crazy busy lately and haven't had time to put together a
    real release. But the code has made some nice progress in the last 6 weeks
    or so, including T5.2 compatibility and improved ValueEncoder support (trunk
    adds support for multi-key PK's. Take that, tapestry-hibernate! ;). I'm
    also planning on either updating the EntityField, or creating an alternative
    component (and deprecating EntityField) that works better. I have a working
    prototype of said new component in a personal project I'm working on, but it
    still has a couple of quirks that I need to fix before moving it directly
    into T5cayenne.

    Robert
  • Marek Stanisław Wawrzyczny at Sep 7, 2010 at 2:59 am
    Hi,

    It's been a while since I've used Cayenne and so far my dealings with it have been based around dabbling with code that's being handled by more competent people. ;) Having said that, I've used Hibernate for about 4-5 years and have some experience with it so here's my 2c.

    Lazy initialisation

    Yes, it is a problem but there are solutions. We used Spring frameworks extensively and Spring's OSIV filter solves the HiB problem to a large degree http://forum.springsource.org/showthread.php?t=57441 You will still encounter problems with mapping of relationships - you have to be careful about joins (eager or lazy), locking. There are bugs when defining/using more complex relationships, I can't remember the details but I remember a particular bug that involved deep relationship fetch/ordering using a particular Collection type being a few years old… there were a few of these.


    Hibernate's popularity

    Much of it is due to its momentum but some of the adoption might also be dictated by the support within IDEs or simply the range of plugins available. Many of these are ORM agnostic, being based around the Persistence JSRs (which admittedly are based on HiB). For example, I am curious about the Persistence module support within NetBeans. A direct benefit of setting up persistence presence in a framework is that you can then use the Web Services plugin to generate RESTful services based on Entities defined in the Persistence framework. The premise sounds neat. I've been trying to find a Cayenne Entity Manager that's needed to setup Persistence support for Cayenne in NetBeans - not sure if such beast exists.

    Of course, the availability of these tools makes a rather mundane task potentially* much easier. Hibernate doesn't just integrate with IDEs. This pretty much extends to frameworks - there's HiB support in Tapestry, Struts, Spring, etc… Whether this support is basic or not, or even necessary, a Google search by a curious user will reaffirm that it is a "supported" framework.

    So, I don't think that Hibernate's popularity should be dismissed simply as a manager's decision.


    * Well, if it actually works… :)


    Cheers,

    Marek Wawrzyczny


    On 06/09/2010, at 04:21, Joe Baldwin wrote:

    Hi,

    I am again responsible for making a cogent Cayenne vs Hibernate Comparison. Before I "reinvent the wheel" so-to speak with a new evaluation, I would like to find out if anyone has done a recent and fair comparison/evaluation (and has published it).

    When I initially performed my evaluation of the two, it seemed like a very easy decision. While Hibernate had been widely adopted (and was on a number of job listings), it seemed like the core decision was made mostly because "everyone else was using it" (which I thought was a bit thin).

    I base my decision on the fact that Cayenne (at the time) supported enough of the core ORM features that I needed, in addition to being very similar conceptually to NeXT EOF (which was the first stable Enterprise-ready ORM implementations). Cayenne seems to support a more "agile" development model, while being as (or more) mature than EOF. (In my opinion. :) )

    It seem like there is an explosion of standards, which appear to be driven by "camps" of opinions on the best practices for accomplishing abstraction of persistence supporting both native apps and highly distributed SOA's.

    My vote is obviously for Cayenne, but I would definitely like to update my understanding of the comparison.

    Thanks,
    Joe

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupuser @
categoriescayenne
postedSep 5, '10 at 7:23p
activeSep 29, '10 at 5:22p
posts24
users8
websitecayenne.apache.org

People

Translate

site design / logo © 2022 Grokbase