Announcement Announcement Module
Collapse
No announcement yet.
Object identity with HibernateTemplate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Object identity with HibernateTemplate

    Hi!
    I am using Spring with Hibernate, and i am confused by the following (taken from a junit test):

    Code:
    Subject subject1a = (Subject) getHibernateTemplate().find("FROM Subject s WHERE s.title='Subject 1'").get(0);
    Subject subject1b = (Subject) getHibernateTemplate().find("FROM Subject s WHERE s.title='Subject 1'").get(0);
    
    // the following fails!
    assertTrues(subject1a==subject1b);
    I read the Hibernate manual on Identity/Equals, and i thought that the two find's should return exactly the same object (in terms of Java-VM identity). Am i wrong about that?

    I tried the same with a "plain" Hibernate session:
    Code:
    Subject subject1a = (Subject) hibernateSession.find("FROM Subject s WHERE s.title='Subject 1'").get(0);
    Subject subject1b = (Subject) hibernateSession.find("FROM Subject s WHERE s.title='Subject 1'").get(0);
    
    // the following is true!
    assertTrue(subject1a==subject1b);
    And this works. I thought HibernateTemplate would store the HibernateSession in a thread bound variable and reuse it on the next call. But apparently in the first code snippet a new session is opened for every find-call.

    Did i miss something important?

    I will post more information about my setup below.

    Thanks for your help!
    Sebastian

  • #2
    BTW: I also tried this identity comparison in a controller, with my (otherwise working) Managers and DAOs. The comparison failed there, too...

    In the JUnit test i setUp the following:
    Code:
    sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
    sessionFactory.afterPropertiesSet();
    
    hibTempl = new HibernateTemplate((SessionFactory) sessionFactory.getObject());
    (the method getHibernateTemplate() in my JUnit test simply returns hibTempl)

    Comment


    • #3
      Spring will only do the ThreadLocal binding in the context of a single transaction. You need to create a transaction in your tests, using Spring's declarative tx management or programmatically with the HibernateTransactionManager. I typically use an abstract integration test superclass that creates a transaction in setUp() and rolls it back in tearDown().

      Comment


      • #4
        This is why I personally also always set up my HibernateTemplates with the allowCreate flag set to off (session must already exist, presumably set up alongside the transaction by HibernateTransactionManager or another transaction manager+HibernateInterceptor).

        With the flag set to the default true, it's too easy to run code out of a transaction, and accidentally create a session when you don't realize it...

        Regards,

        Comment


        • #5
          Hi Rod, Colin!

          Thanks for your replies! This solved my problem... :-)

          Sebastian

          Comment

          Working...
          X