Announcement Announcement Module
No announcement yet.
Cache issue - transaction-scoped Hibernate Sessions Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cache issue - transaction-scoped Hibernate Sessions

    Hello there,

    I configured Spring to use transactions around application classes only (eg. class AppEditArtifact, method saveArtifact(Artifact a)), because these classes contain use case implementations. I'm using WebWork, and WebWork actions are not included in the transaction.

    In that context, an object retrieved from a Hibernate session in the WebWork action is not the same as one retrieved in the application class even if they have the same Hibernate Id. Searching the forums I found out that this is because Spring uses transaction-scoped Hibernate Sessions. Therefore, the sessions are different and I can't benefit from Hibernate's cache.

    Just so you know, I want to use cache primarily because I wouldn't have to override equals() on my domain objects and they work, because both objects would be the same in memory.

    What is the best way (or any way) to go around this?
    • - Can I configure the action method to PROPAGATION_REQUIRED? If I do so, will it be included in the transaction and therefore use the same hibernate session?

      - Can I create some other form of cache? Any suggestions on which form?

      - Should I forget about using cache and override equals, preferrably using some tool like Jakarta's commons-lang?

    Any answers, pointers and RTFMs are welcome.

    Thanks in advance,
    - Vítor Souza

  • #2
    I usually implements equals / hashCode / compareTo in my domain class. I also use Jakarta Commons. You should however pay attention to these issues:
    - do not use reflection based approach
    - Overcoming the hashCode() / object identity
    Last edited by robyn; May 19th, 2006, 05:23 AM.


    • #3
      Hi Omar,

      Thanks a lot for your response. It really helped.

      I chose to implement Jason's approach with UUIDs. But since I don't like the idea of a 32-char string as primary-key, I'll keep my persistence Ids the way they are and add a property "uuid" for each persistent object.

      However, I have a question. It's more like a poll, actually. I'd like to hear opinions from as many people as possible...

      Say there are two approaches to this situation:

      (a) have a cache between the business layer and the persistence layer to make sure the same object is always at the same position in memory, so to use java.lang.Object's implementation of hashCode() and equals();

      (b) have a uuid property set at construction time, store it in the database and use it as base for hashCode() and equals();

      Which approach would work better with Spring? Which one do you guys prefer (maybe you prefer even another one)?

      I thank in advance anyone who contributes with his/her opinion.

      Vítor Souza


      • #4
        I have a late reply but better later then never. In my application me and the team have the exact same problem (as Jason). In my opinion you want the PK to be the 32-char string because that identifies your object in any context.

        Think about the 'finders' scenario - if you have the UUID as a property you have to :

        1. do the search after the ID which makes the UUID redundant.
        2. do the seach after the UUID which makes the ID useless.

        I think the hit on the database can be alleviated to some extend with indexes - I'm not a DB expert. Moreover, this problem occurs if your tables have a lot (I mean LOT) of entries and seaching takes a long time.

        Commenting on your approaches:

        a. caching is a useful but possible dangerous thing. I won't implement it(think about synchronization issues (brrr)). A good application runs okay without cache. (that's why we are now in the process of moving out of EJB and into Spring).

        b. as I said before I'm planning of using it as PK, all over the hashCode and equals (most probably in a super class that all other properties extend).


        • #5
          I guess what we need to do is measure the performance lost when the PK is changed to a VARCHAR in different scenarios. Maybe it pays to have some redundancy for the sake of performance.

          In any case, I'll stick to UUID as properties. It's been working fine. I *only* use it in equals() and hashCode() (not for finder methods), and that is done automatically by a helper class, so I hardly even remember the UUID exists. I only have to include it in the DB table and Hibernate's mapping file for it to work.

          Maybe a deeper study on the subject will arise in the blogosphere soon... Let's wait.



          • #6
            In my case I prefer to use UUID also because it allows different database to be merged (migrated from old versions into existing ones) - ofc, this might not be your case.


            • #7
              Indeed it's perfect for database merging/moving. Just something else to add to the PROs list. I'll just have to measure how big is the performance/space hit.

              Thanks a lot for your replies. It really helps to discuss these issues with other developers.



              • #8
                Same here - don't forget to post back your benchmark. It will help others (including me).


                • #9
                  Just for the record - HB provides an UUID implementation out of the box. The downside is that objects will get an ID only after they have been written into the DB so using it as a discriminator for new POJOs(w/o id) will not work.

                  P.S.Calling the JB library to get the id doesn't work as they are dependent on serveral HB components so the JGUID library is a better choice in this case.

                  Update: After searching the forum and looking at the sources it appears that it's possible to use the generators without any dependencies on the HB internals. See