OpenSessionInViewFilter и пользовательская пружина DAO - PullRequest
0 голосов
/ 01 апреля 2011

Я кодировал пользовательский универсальный DAO следующим образом:

public abstract class DAOImpl<T, PK extends Serializable> implements DAO<T, PK> {

private SessionFactory sessionFactory;
protected Logger log = null;

private Class<T> type;

public DAOImpl(Class<T> type) {
    this.type = type;
}

public PK insert(T o) {
    return (PK) getSession().save(o);
}
....
/**
 * {@inheritDoc}
 */
public SessionFactory getSessionFactory() {
    return sessionFactory;
}

/**
 * {@inheritDoc}
 */
public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}

/**
 * {@inheritDoc}
 */
public Session getSession() {
    return SessionFactoryUtils.getSession(sessionFactory, Boolean.FALSE);
}
}

Все операции BO являются транзакционными.

web.xml

<filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>com.foo.bar.util.filters.MyOSIVFilter</filter-class>
<init-param>
    <param-name>sessionFactoryBeanName</param-name>
    <param-value>sessionFactory</param-value>
</init-param>
</filter>

MyOSIVFilter является подклассом OpenSessionInViewFilter, который закрывает сессии следующим образом:

public void closeSession(Session session, SessionFactory sessionFactory){

    session.flush();
    super.closeSession(session,sessionFactory);
}

hibernate.cfg.xml

<session-factory name="foo">

    <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
    <property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property>

    <property name="hibernate.connection.datasource">XXXXXXXXXX</property>

    <property name="show_sql">yes</property>
    <property name="hibernate.jdbc.batch_size">10</property>
    <property name="hibernate.cache.use_second_level_cache">false</property>
    <property name="cache.use_query_cache">false</property>
    <property name="hibernate.connection.autocommit">false</property>
    <property name="hibernate.connection.release_mode">after_transaction</property>

beans.xml (выдержка)

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>

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

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="get*" read-only="true" />
        <tx:method name="read*" read-only="true"/>
        <tx:method name="query*" read-only="true"/>
                    <tx:method name="insert*" propagation="REQUIRES_NEW" rollback-for="java.lang.Throwable" />

простой код

public void queryBusiness(){
    MyObject obj = objDAO.find(111);
    insertProcess1(obj);
    insertProcess2(obj);
}

Проблема: открыты несколько сессий Hibernate. Журналы показывают, что OpenSessionInViewFilter открывает новый сеанс, но кто получает другие?

1 Ответ

1 голос
/ 03 апреля 2011

Когда Spring создает новую транзакцию, он также создает новую сессию. Я видел много людей, имеющих такую ​​же проблему. Например, посмотрите здесь:

http://www.jroller.com/agileanswers/entry/beware_propagation_requires_new_with

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...