【问题标题】:Hibernate+Spring SessionFactory configurationHibernate+Spring SessionFactory 配置
【发布时间】:2015-12-31 09:35:51
【问题描述】:

配置SessionFactory的正确方法是什么?

如果我这样做:

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
             p:dataSource-ref="dataSource"
             p:packagesToScan="ua.com.javer.flowerexpert"/>

<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"
            p:sessionFactory-ref="sessionFactory" />

我收到此错误:

nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread

如果我改成AnnotationSessionFactoryBean:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
             p:dataSource-ref="dataSource"
             p:packagesToScan="ua.com.javer.flowerexpert"/>

我明白了:

nested exception is java.lang.NoClassDefFoundError: [Lorg/hibernate/engine/FilterDefinition;

即使在一些较旧的项目中 hibernate3.annotation.AnnotationSessionFactoryBean 工作正常。

我的pom.xml 包含:

        <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.0.1.Final</version>
        <exclusions>
            <exclusion>
                <groupId>org.hibernate.javax.persistence</groupId>
                <artifactId>hibernate-jpa-2.1-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.0.1.Final</version>
    </dependency>

    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.version}</version>
    </dependency>

这是我的 Service 类:

@Service("colorsService")
@Transactional
public class ColorsService {
@Autowired
private ColorDao colorDao;

public List<Color> getAllColors() {
    return colorDao.getAllColors();
}
}

这是DAO

@Component
@Repository("colorDao")
public class ColorDaoHibernate implements ColorDao {

@Autowired
private SessionFactory sessionFactory;

public ColorDaoHibernate() {
}

@Override
public List<Color> getAllColors() {
    Session session = sessionFactory.getCurrentSession();
// StatelessSession session = sessionFactory.openStatelessSession();
    Query query = session.createQuery("FROM Color");
    return  query.list();
}
}

注意:

如果我在 DAO 类中使用 sessionFactory.openStatelessSession(); hibernate5.LocalSessionFactoryBean 在会话配置中不会导致问题。

但重点是 - 我想使用sessionFactory.getCurrentSession(); 我怎样才能做到这一点?

【问题讨论】:

    标签: java spring hibernate sessionfactory


    【解决方案1】:

    好的,问题解决了!

    在我的mvc-dispatcher-servlet.xml 中我有:

        <context:component-scan base-package="ua.com.javer.flowerexpert" />
    

    同时我有:

    <context:component-scan base-package="ua.com.javer.flowerexpert.dao"/>
    

    dao-context.xml 中,所以ua.com.javer.flowerexpert.dao 包被扫描了两次。

    我已将mvc-dispatcher-servlet.xml 中要扫描的软件包更改为:

        <context:component-scan base-package="ua.com.javer.flowerexpert.controller" />
    

    只扫描ua.com.javer.flowerexpert.controller 包(而不是dao)。现在它正在工作。

    【讨论】:

      【解决方案2】:

      希望您在 spring 配置文件中启用了transaction 支持。如果没有,请使用&lt;tx:annotation-driven&gt; 启用它

      另外,如下声明transactionManager

      <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          <property name="dataSource" ref="dataSource"/>
      </bean>
      

      尝试从ColorsService 中删除@Transactional,如下所示:

      @Service("colorsService")
      public class ColorsService {
      @Autowired
      private ColorDao colorDao;
      
      public List<Color> getAllColors() {
          return colorDao.getAllColors();
      }
      }
      

      并将其添加到ColorDaoHibernate:

      @Repository("colorDao")
      public class ColorDaoHibernate implements ColorDao {
      
      @Autowired
      private SessionFactory sessionFactory;
      
      public ColorDaoHibernate() {
      }
      @Transactional
      @Override
      public List<Color> getAllColors() {
          Session session = sessionFactory.getCurrentSession();
      // StatelessSession session = sessionFactory.openStatelessSession();
          Query query = session.createQuery("FROM Color");
          return  query.list();
      }
      }
      

      编辑sessionFactory bean 定义如下:

      <bean id="hibernateProps"
                      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
                      <property name="properties">
                          <props>
                              <prop key="hibernate.current_session_context_class">thread</prop>
                          </props>
                      </property>
                  </bean>
      
          <bean id="sessionFactory"
                      class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
                      p:dataSource-ref="dataSource" p:packagesToScan="ua.com.javer.flowerexpert"
                      p:hibernateProperties-ref="hibernateProps" />
      

      【讨论】:

      • 添加了 hibernateProps - 有一个新的异常:org.hibernate.HibernateException: createQuery is not valid without active transaction
      • 顺便说一句,有人告诉here,@Transctional 注释应该放在 Service 方法上,而不是 DAO 方法上。
      • 一件事要确定,你的spring配置文件中有&lt;mvc:annotation-driven /&gt;
      • 是的,我在 mvc-dispatcher-servlet.xml 文件中有
      • 谢谢你,@Arpit!问题解决了。现在就给出答案
      猜你喜欢
      • 2013-01-26
      • 1970-01-01
      • 2011-12-28
      • 2017-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-06
      • 2012-06-10
      相关资源
      最近更新 更多