【问题标题】:Spring injection of SessionFactory with inheritance giving NullPointers带有继承给 NullPointers 的 SessionFactory 的 Spring 注入
【发布时间】:2011-12-20 18:28:11
【问题描述】:

在我的设计中,我所有的 daos 都继承自一个父类,这个父类包含 hibernateTemplate 字段和一个 setSessionFactory,它在使用 spring 设置会话时创建 hibernateTemplate

这里的问题是,即使它似乎已设置,但当我实际执行代码并且调用 daos 时,hibernateTemplate 对象似乎为空。但是,当我使用会话工厂注入 Dao 对象而不是父泛型类时,它的工作原理就像一个魅力

AbstractDaoSupport 类的部分

/** The hibernate template. */
private HibernateTemplate hibernateTemplate;

/**
 * Sets the session factory.
 *
 * @param sessionFactory the new session factory
 */
public void setSessionFactory(SessionFactory sessionFactory) {
    this.setHibernateTemplate(new HibernateTemplate(sessionFactory));
}

/**
 * Sets the hibernate template.
 *
 * @param hibernateTemplate the hibernateTemplate to set
 */
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
    this.hibernateTemplate = hibernateTemplate;
}

这是当前运行时hibernateTemplate为空的有问题的代码

  <!-- the DataSource for application usage -->
    <bean id="applicationDataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/taxidb"/>
        <property name="username" value="root"/>
        <property name="password" value="abc"/>
   </bean>      

    <bean id="daoSessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="applicationDataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.iit.awt.application.domain.Driver</value>
                <value>com.iit.awt.application.domain.DriverRealTimeCurrentLocation</value>
                <value>com.iit.awt.application.domain.Journey</value>
                <value>com.iit.awt.application.domain.Customer</value>
                <value>com.iit.awt.application.domain.SystemConstants</value>
                <value>com.iit.awt.application.domain.DriverRequest</value>             
                <value>com.iit.awt.application.domain.Account</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>


    <bean id="transactionManager" 
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="daoSessionFactory"/>
    </bean> 

    <!-- JPA Daos -->
    <bean id="abstractDaoSupport" class="com.iit.awt.platform.support.AbstractDaoSupport">
        <property name="sessionFactory" ref="daoSessionFactory" />
    </bean>

这是代码起作用的时候,而不是上面“JPA Daos”注释下的最后一段代码,下面是那里

<bean id="driverLocationDao" class="com.iit.awt.application.dao.impl.DriverLocationDaoImpl">
    <property name="sessionFactory" ref="daoSessionFactory" />
</bean>  

要注意的另一件事是该类以前是抽象的,我尝试使用“abstract=true”以及让它非抽象当前的方式

有人知道为什么 hibernateTemplate 对象为空吗?

非常感谢任何帮助

【问题讨论】:

  • 请贴出你的 abstractdao 的类签名

标签: java hibernate spring dependency-injection dao


【解决方案1】:

您的问题

public void setSessionFactory(SessionFactory sessionFactory) {
    this.setHibernateTemplate(new HibernateTemplate(sessionFactory));
}

你不是实际上在这里设置sessionFactory,所以它会保留null


更好的方法

我是按照下面的方式做的,为什么要自己创建模板..

AbstractDAO

public abstract class BaseAbstractGenericDao<EntityType, IDType extends Serializable> extends HibernateDaoSuppor  {

}

HibernateTemplate Bean 定义 使用会话工厂注入

 <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <constructor-arg>
            <ref bean="sessionFactory"/>
        </constructor-arg>
    </bean>

HibernateTemplate Bean 定义 带有会话数据源注入和其他属性设置器注入

 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
          p:dataSource-ref="dataSource">
        <property name="annotatedClasses">
            <list>...</list>
</property>
<bean>

【讨论】:

  • 非常感谢您的回答,我使用了 HibernateDaoSupport 并且它有效
  • 从 Spring 3.1 开始,不鼓励使用 HibernateTempalate 和 HibernateDaoSupport。请查看他们的文档以获取更多信息
【解决方案2】:

谁在你的代码中注入了 hibernateTemplate ?如果你正在扩展 HibernateDaoSupport ,你只需要注入 sessionFactory 。 getHibernateTemplate() 方法在其父类中查找休眠模板。这就是为什么下面的代码有效的原因

<bean id="driverLocationDao" class="com.iit.awt.application.dao.impl.DriverLocationDaoImpl">
   <property name="sessionFactory" ref="daoSessionFactory" />
</bean>  

这里不需要休眠模板初始化。如果您不扩展 hibernateDaoSuppor,则必须像 @Jigar Joshi 提到的那样注入模板。

请注意,根据 Spring 3 的建议 here,不建议使用 Hibernate 模板

NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can also be coded 
in plain Hibernate style. Hence, for newly started projects, consider adopting the
standard Hibernate3 style of coding data access objects instead, based on 
SessionFactory.getCurrentSession(). 

【讨论】:

    猜你喜欢
    • 2021-11-05
    • 2017-10-10
    • 1970-01-01
    • 2016-05-04
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 2018-02-04
    相关资源
    最近更新 更多