Women in Technology

Hear us Roar



Article:
  Don't Let Hibernate Steal Your Identity
Subject:   Thanks
Date:   2006-09-13 23:20:45
From:   MartinZdila
Thanks for nice article :-)
Full Threads Newest First

Showing messages 1 through 3 of 3.

  • Thanks
    2007-01-11 05:49:55  rakeshpatel1 [View]

    seems the Hibernate authors are not too impressed with this article:

    http://forum.hibernate.org/viewtopic.php?t=967211
    • Thanks
      2007-01-14 14:10:15  jbrundege [View]

      Thanks rakeshpatel1 for pointing this out. Yes, they didn't like this article at all. We've had a quite a discussion over the past week which you can read from the above link.

      Here's a quick summary:
      Their criticism was that I launched into a discussion of object identity with the assumption that you had to override equals() and hashCode(). Their position is that you only have to override these methods if you use detached objects. And they feel there are much better alternatives to using detached objects. This is fair. When I've used application-assigned UUIDs I've also used detached objects, which I didn't even point out much less mention the alternatives.

      The alternatives basically involve keeping the Hibernate Session around in between transactions. Since the Session holds a map of persisted objects, if you never discard the Session you're always guarenteed to return the same instance of an object each time you request it. You can then use the default implementation of equals() and hashCode() since you won't load two separate instances of the same object. You can still use application-assigned ids on your objects and override these methods if you want to, but a key motivation for doing so is gone.

      There are several ways to avoid discarding the Session between requests. If you have a two-tiered application (ui layer, service layer, and data access layers are all replicated on each of your web servers while the database may be on another machine), you can put the Hibernate Session on the HttpSession. This can be done with an interceptor or servlet filter that works before the rest of your ui, so you donít contaminate your ui or service layer with any persistence code. The interceptor can then call the Hibernate method ManagedSessionContext.bind(session), which binds the Session to a ThreadLocal map of Sessions where it can be picked up again and used by your Data Access Object. In this way something at the front of your application (ui interceptor or servlet filter) can manage the creation and storage of a Session for each user conversation, and the DAO at the back of the application can use it without having to explicitly pass it through all the intervening application layers (which shouldn't have to know what persistence framework you're using).

      If you have a stateless layer between the web server and the DAO (such as a 3-tier architecture using stateless session EJBs) this won't work. That is, if the DAO is on a different machine than the web server it won't have access to a ThreadLocal bound Hibernate Session. In that case you can't store the Hibernate Sessions in the HttpSession, and will have to store them in the service layer. One way to do this is with Stateful Session EJBs.

      The terminology has shifted around a bit, so just to clarify: older documentation on this refers to it as "long session", newer documentation as "extended session". There's also many references to it as the "session-per-conversation" strategy to highlight the idea of scoping the Session to a conversation between the user and the app which involves multiple request/response cycles. With the EJB 3.0 spec and the Java Persistence API the relevant interface is named EntityManager instead of Session, so the terminology sometimes shifts to the more generic "extended persistence context". In this case the "persistence context" could be a Session or EntityManager.

      Here's some links to the relevant documentation:

      The best descriptions are in the books:
      Hibernate in Action: Section 8.2.4: Using a long session
      Java Persistence with Hibernate: Section 11.2.3: Extending a Session for a conversation

      Sparce description in the Reference Documentation:
      http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#transactions-optimistic-longsession

      Related sections in the JPA EntityManager documentation:
      http://www.hibernate.org/hib_docs/entitymanager/reference/en/html_single/#architecture-ejb-persistctxscope
      http://www.hibernate.org/hib_docs/entitymanager/reference/en/html_single/#d0e1783

      Section in the wiki on the open session in view pattern:
      http://www.hibernate.org/43.html#A5
      • Thanks
        2007-12-13 10:03:47  haywardl [View]

        My project involves a webapp and desktop app. The desktop app involves detached object. We do not want to use extended session. The approach we take is similar to yours. The entities still have their own primary keys. However, a "uuid" attribute is added to the superclass of all entities. The uuid field is persisted in the database as well. This field gets set at object creation time exactly the same as you describe in your article. The equals and hashCode are based on the "uuid" field.