Конфигурация Hibernate+Spring SessionFactory

Как правильно настроить 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();
}
}

ВНИМАНИЕ:

Если я использую sessionFactory.openStatelessSession(); в классе DAO, hibernate5.LocalSessionFactoryBean в конфигурации сеанса не вызовет проблем.

Но суть в том, что я хочу использовать sessionFactory.getCurrentSession(); Как мне этого добиться?


person Anatolii Stepaniuk    schedule 03.10.2015    source источник


Ответы (2)


Надеюсь, вы включили поддержку транзакций в ваш файл конфигурации spring. Если нет, включите его с помощью <tx:annotation-driven>

А также объявите transactionManager следующим образом:

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

Попробуйте удалить @Transactional из ColorsService, как показано ниже:

@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();
}
}

Отредактируйте определение bean-компонента sessionFactory, как показано ниже:

<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" />
person Arpit Aggarwal    schedule 03.10.2015
comment
Добавлен hibernateProps - появилось новое исключение: org.hibernate.HibernateException: createQuery is not valid without active transaction - person Anatolii Stepaniuk; 03.10.2015
comment
Кстати, здесь сказано, что аннотацию @Transctional следует размещать в методах службы, а не в методах DAO. - person Anatolii Stepaniuk; 03.10.2015
comment
Одна вещь, чтобы убедиться, что у вас есть <mvc:annotation-driven /> в вашем файле конфигурации spring? - person Arpit Aggarwal; 03.10.2015
comment
Да, у меня есть ‹mvc:annotation-driven/› в файле mvc-dispatcher-servlet.xml. - person Anatolii Stepaniuk; 03.10.2015
comment
Спасибо, @Арпит! Задача решена. Сейчас дам ответ - person Anatolii Stepaniuk; 03.10.2015

Хорошо, проблема решена!

В моем 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). Теперь это работает.

person Anatolii Stepaniuk    schedule 03.10.2015