Announcement Announcement Module
Collapse
No announcement yet.
Inject HibernateTemplate into DAO Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Inject HibernateTemplate into DAO

    Ok, I'm getting a strange error when I do this. HibernateTemplate is a POJO, and I want to inject it into my BaseDAO so that I can also use JdbcTemplate (through DI) instead of using single-inheritance for one (HibernateDaoSupport) and then an ugly hack to get a JDBC template.

    here's my applicationContext:

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate.Hibernate Template">
    <property name="sessionFactory"><ref bean="sessionFactory"/></property>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
    <property name="dataSource"><ref bean="promiseds"/></property>
    </bean>

    <bean id="baseDAO" class="sg.com.crownsys.promise.dao.implementation. BaseDAOImplementation">
    <property name="hibernateTemplate"><ref bean="hibernateTemplate"/></property>
    <property name="jdbcTemplate"><ref bean="jdbcTemplate"/></property>
    </bean>

    Now my other DAOs just inherit from baseDAO so they don't need any DI, but in my unit test for the baseDAO I get a null pointer exception when I try to get the sessionFactory from the HibernateTemplate that Spring wired for me.

    It seems as if Spring isn't injecting the HibernateTemplate. But I can't see in the docs what else I need to do. I'm assuming that Spring can instantiate one of it's own classes as a bean and use DI to wire up the session factory.

    I can't see the problem right now, can anyone tell me what I'm doing wrong?

    Spring 1.1.5 (I think)
    using HibernateTemplate (not Hibernate3)

    Stack trace:

    java.lang.NullPointerException
    at sg.com.crownsys.promise.dao.implementation.BaseDAO Implementation.save(BaseDAOImplementation.java:164 )
    at sg.com.crownsys.promise.dao.implementation.RoleDAO Implementation.saveRole(RoleDAOImplementation.java :44)
    at sg.com.crownsys.promise.dao.test.BaseDAOImplementa tionTest.setUp(BaseDAOImplementationTest.java:26)
    at junit.framework.TestCase.runBare(TestCase.java:125 )
    at junit.framework.TestResult$1.protect(TestResult.ja va:106)
    at junit.framework.TestResult.runProtected(TestResult .java:124)
    at junit.framework.TestResult.run(TestResult.java:109 )
    at junit.framework.TestCase.run(TestCase.java:118)
    at junit.framework.TestSuite.runTest(TestSuite.java:2 08)
    at junit.framework.TestSuite.run(TestSuite.java:203)
    at org.apache.tools.ant.taskdefs.optional.junit.JUnit TestRunner.run(JUnitTestRunner.java:289)
    at org.apache.tools.ant.taskdefs.optional.junit.JUnit TestRunner.launch(JUnitTestRunner.java:656)
    at org.apache.tools.ant.taskdefs.optional.junit.JUnit TestRunner.main(JUnitTestRunner.java:558)

    Kev

  • #2
    1. turn on logging inside Spring and in your application.
    2. make sure the NPE is from getHibernateTemplate and not something else written on the same code line.

    This way you'll find out what the hibernate template is and what is causing the NPE.

    Comment


    • #3
      solution - not sure if it's optimal

      Thanks for the "Turn on logging", having just fallen off the back of a yokel cart I needed that advice :?

      I tracked it down more through intuition than the massive amounts of logging that Spring outputs to the log. Basically whenever I called the bean directly it worked, but as it was a superclass, I was calling it's methods from a subclass. When I did this, Spring instantiated a new bean, but *didn't* wire this new instance with the appropriate dependencies, before the subclass called the methods. - I didn't re-declare the dependencies in the subclasses.

      Part of my drive is to reduce the xml, without increasing the coupling, so I didn't want to inject the dependencies in each of the subclasses - this works fine, but increases the xml. My solution was to declare the original superclasses dependencies as static, thereby giving me actual values when I inherit from it.

      Why Spring decided not to wire up a new instance of the superclass when it went to the trouble of wiring up the original instance [shrug]?

      I think this is a problem in general, as it means that you have to re-inject on every bean declaration.

      Still it works, my worry now is that there'll be a subtle bug introduced because the beans are sharing one instance of the properties I injected, although in this case the properties are HibernateTemplate and JdbcTemplate, and there shouldn't be a reason to change them when the server is running.

      Kev

      Comment


      • #4
        Why Spring decided not to wire up a new instance of the superclass when it went to the trouble of wiring up the original instance [shrug]?
        Umm, because that's how it works?

        Singleton beans are all wired up at the moment the context is loaded. The only way to get a wired bean is by doing ctx.getBean() or getting an indirect reference through some other wired instance you got through ctx.getBean(). If you create your subclasses instances using new, they have nothing to do with Spring. QED.

        Comment


        • #5
          If you create your subclasses instances using new, they have nothing to do with Spring.
          However I was getting my beans (subclasses) from the context:

          Code:
          rDao = (RoleDAO) CTX.getBean("roleDAO");
          It still didn't give me the wired up superclass, instead it instantiated a new superclass (unwired).

          I've already found a way to resolve the problem I had, but why does Spring bother to wire up an instance (my superclass bean), but then not refer to it? It wasn't decalred as a singleton bean, but changing it to a singleton made no difference and I was given a new instance, seems odd that's all.

          Comment


          • #6
            Originally posted by foamdino
            If you create your subclasses instances using new, they have nothing to do with Spring.
            However I was getting my beans (subclasses) from the context:

            Code:
            rDao = &#40;RoleDAO&#41; CTX.getBean&#40;"roleDAO"&#41;;
            It still didn't give me the wired up superclass, instead it instantiated a new superclass (unwired).

            I've already found a way to resolve the problem I had, but why does Spring bother to wire up an instance (my superclass bean), but then not refer to it? It wasn't decalred as a singleton bean, but changing it to a singleton made no difference and I was given a new instance, seems odd that's all.
            Hard to tell, there is no roleDao definition in the context you showed us in your first post.

            Comment

            Working...
            X