1

次の問題があります。私の改札アプリケーション内で @Transactional 注釈を使用したいと考えています。私のすべての DAO は @Component アノテーションでロードされます。

@Component
@Transactional(propagation = Propagation.SUPPORTS)
public class AccountHibernateDataAccessHelper implements
    AccountDataAccessHelper
{
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void saveOrUpdate(T dataObject)
{
    try
    {
        Session session = getSessionProvider().getSession();
        session.saveOrUpdate(dataObject);
    }
    catch (HibernateException e)
    {
        String message = "Failed to batch save or update " + dataObject;
        log.error(message, e);
    }
}
@SuppressWarnings("unchecked")
public <R extends T> List<R> list(Class<R> class1)
{
    Asserts.assertNotNull("class1", class1);
    try
    {
        return createCriteria(class1).setCacheable(true)
                .setCacheRegion(getQueryCacheRegion()).list();
    } catch (HibernateException e)
    {
        String message = "Failed to get a list of" + class1;
        log.error(message, e);
        throw new DataAccessException(message, e);
    } catch (RuntimeException e)
    {
        log.error(e.toString(), e);
        throw new DataAccessException(e);
    }
}

}

My AccountDataAccesshelper は次のインターフェースを実装します

public interface DataAccessHelper<T>
{
public Serializable save(T dataObject);

public void saveOrUpdate(T dataObject);

public void update(T dataObject);

public void delete(T dataObject);

public void evict(T dataObject);

}

次に、私の appllicationcontext.xml 設定です。

<context:component-scan base-package="nl.response.webapp" />
<context:annotation-config />

    <!-- hibernate session factory -->
<bean id="sessionFactory" class="nl.response.responseframework.app.ResponseAnnotationSessionFactoryBean">
    <property name="dataSource" ref="mainDataSource" />
    <property name="hibernateProperties">
        <map>
            <entry key="hibernate.session_factory_name" value="wtxwebapp" />
            <entry key="hibernate.transaction.factory_class" value="org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory" />
            <entry key="hibernate.cache.query_cache_factory"
                value="nl.response.responseframework.service.InvalidatableQueryCacheFactory" />
            <entry key="hibernate.cache.region.factory_class"
                value="nl.response.wtxwebapp.core.hibernate.WtxWebAppEhCacheRegionFactory" />
            <entry key="hibernate.cache.region_prefix" value="hibernate-" />
            <entry key="hibernate.generate_statistics" value="false" />
            <entry key="hibernate.current_session_context_class" value="thread" />
            <entry key="hibernate.cache.use_structured_entries" value="true" />
            <entry key="hibernate.cache.use_query_cache" value="true" />
            <entry key="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        </map>
    </property>
</bean>

   <bean id="mainDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
        <property name="driverClass" ref="hibernate.connection.driver_class" />
        <property name="jdbcUrl" ref="hibernate.connection.url" />
        <property name="username" ref="hibernate.connection.username" />
        <property name="password" ref="hibernate.connection.password" />
        <property name="poolName" ref="hibernate.connection.username"/>
        <property name="idleConnectionTestPeriodInMinutes" value="60" />
        <property name="idleMaxAgeInMinutes" value="240" />
        <property name="maxConnectionsPerPartition" value="50" />
        <property name="minConnectionsPerPartition" value="5" />
        <property name="partitionCount" value="2" />
        <property name="poolAvailabilityThreshold" value="10" />
        <property name="acquireIncrement" value="4" />
        <property name="statementsCacheSize" value="50" />
        <property name="releaseHelperThreads" value="3" />
        <property name="serviceOrder" value="LIFO" />
    </bean>

<bean id="txManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="dataSource" ref="mainDataSource" />
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager"/>

セッションプロバイダーは、次のようにセッションを提供します

public Session getSession()
{
    getSessionFactory().openSession();
}

上記のセッションメソッドを使用すると、何もコミットされず、接続が適切に閉じられないため、巨大なバッチでエラーが発生します。

getSessionFactory.getCurrentSession() を使用すると、次のエラーが発生します

createCriteria は、アクティブなトランザクションがないと無効です

私は何が欠けていますか?私はこれをすでに数日間機能させようとしていますが、オプションから抜け出しています:S

4

1 に答える 1

1

Sessionに電話するたびに新しいものを開いていますgetSession()

代わりにこれを試してください:

public Session getSession() {
    SessionFactoryUtils.getSession(getSessionFactory(), true);
}

これにより、毎回新しいセッションを開くのではなく、オンデマンドで作成された Spring 管理の休止状態セッションが取得されます。

OpenInViewSessionFilterまたは同等のものを使用しない場合でも、トランザクション内にいる場合を除き、クエリごとに新しいセッションを作成することに注意してください。しかし今回は、Spring が自動的にそれらを閉じます。

于 2012-02-08T18:36:35.910 に答える