OpenSessionInViewFilter和自定义弹簧DAO

时间:2011-04-01 11:57:29

标签: hibernate spring transactions

我用这种方式编写了一个自定义通用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(extract)

<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 个答案:

答案 0 :(得分:1)

一旦Spring开始创建新事务,它也会创建一个新会话。我见过很多人都有同样的问题。例如,请看这里:

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