Hibernate+Spring SessionFactory配置
Hibernate+Spring SessionFactory configuration
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>
这是我的 服务 class:
@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();
class hibernate5.LocalSessionFactoryBean
在会话配置中不会导致问题。
但重点是 - 我想使用 sessionFactory.getCurrentSession();
我怎样才能做到这一点?
希望您在 spring 配置文件中启用了 transaction 支持。如果没有,请使用 <tx:annotation-driven>
启用它
此外,声明 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" />
好的,问题解决了!
在我的 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)。现在可以使用了。
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>
这是我的 服务 class:
@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();
class hibernate5.LocalSessionFactoryBean
在会话配置中不会导致问题。
但重点是 - 我想使用 sessionFactory.getCurrentSession();
我怎样才能做到这一点?
希望您在 spring 配置文件中启用了 transaction 支持。如果没有,请使用 <tx:annotation-driven>
此外,声明 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" />
好的,问题解决了!
在我的 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)。现在可以使用了。