programing

스레드에 바인딩된 최대 절전 모드 세션이 없으며 구성에서는 여기서 트랜잭션이 아닌 세션을 생성할 수 없습니다.

muds 2023. 10. 8. 10:26
반응형

스레드에 바인딩된 최대 절전 모드 세션이 없으며 구성에서는 여기서 트랜잭션이 아닌 세션을 생성할 수 없습니다.

하는 DAO 합니다를 하면 이 합니다.SessionFactory.getCurrentSession()는 .DAO 이 달립니다.@Transactional그리고 나 또한 가지고 있습니다.<tx:annotation-driven/>애플리케이션 컨텍스트 구성 파일에 선언됩니다.

HQL 쿼리를 수행하는 DAO 메서드를 호출할 수 있지만 처음에 최대 절전 모드 세션을 받는 DAO 메서드를 호출할 때마다 다음과 같은 예외가 발생합니다.

SEVERE: Failed to save the object.
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
    at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.getCurrentSession(GenericDaoHibernateImpl.java:56)
    at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.saveOrUpdate(GenericDaoHibernateImpl.java:187)

다음과 같은 응용프로그램 컨텍스트 구성 파일이 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:flex="http://www.springframework.org/schema/flex"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                           http://www.springframework.org/schema/flex
                           http://www.springframework.org/schema/flex/spring-flex-1.0.xsd
                           http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!--  load values used for bean properties  -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <value>applicationContext.properties</value>
        </property>
    </bean>


    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!--  DataSource where objects will be persisted  -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="username" value="${datasource.username}" />
        <property name="password" value="${datasource.password}" />
        <property name="url" value="${datasource.url}" />
        <property name="driverClassName" value="${datasource.driver}" />
    </bean>


    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!-- Factory bean for Hibernate Sessions -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvg</value>
                <value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlObservations</value>
                <value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlStation</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.use_sql_comments">true</prop>
                <prop key="hibernate.jdbc.batch_size">50</prop>
                <prop key="hibernate.query.substitutions">true 1, false 0</prop>
                <prop key="hibernate.max_fetch_depth">6</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddlauto}</prop>
                <prop key="hibernate.cache.use_second_level_cache">${hibernate.use_second_level_cache}</prop>
            </props>
        </property>
    </bean>


    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!--  Transaction Manager bean  -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="hibernateSessionFactory" />
    </bean>


    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!--  enable the configuration of transactional behavior based on annotations  -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <tx:annotation-driven transaction-manager="transactionManager" />


    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!--  DAO for ESRL Station objects  -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <bean id="esrlStationDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlStationDaoHibernateImpl">
        <property name="sessionFactory" ref="hibernateSessionFactory" />
        <property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlStation" />
    </bean>


    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!--  DAO for ESRL Observations objects  -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <bean id="esrlObservationsDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlObservationsDaoHibernateImpl">
        <property name="sessionFactory" ref="hibernateSessionFactory" />
        <property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlObservations" />
    </bean>


    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!--  DAO for ESRL daily average objects  -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <bean id="esrlDailyAvgDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlDailyAvgDaoHibernateImpl">
        <property name="sessionFactory" ref="hibernateSessionFactory" />
        <property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvg" />
    </bean>


</beans> 

일반 DAO 클래스(내 프로그램에서 사용 중인 DAO가 확장됨)는 다음과 같습니다.

package gov.noaa.ncdc.cmb.persistence.dao;

import gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;

/**
 * This class is an implementation of GenericDao<T, PK> using Hibernate.
 */
public class GenericDaoHibernateImpl<T extends PersistentEntity<PK>, PK extends Serializable>
    implements GenericDao<T, PK>
{
    private SessionFactory sessionFactory;

    static private Log log = LogFactory.getLog(GenericDaoHibernateImpl.class);

    private Class<T> persistentClass;

    /**
     * Can be used within subclasses as a convenience method.
     * 
     * @param criterionList the criteria to find by
     * @return the list of elements that match the specified criteria
     */
    protected List<T> findByCriteria(final List<Criterion> criterionList)
    {
        Criteria criteria = getCurrentSession().createCriteria(persistentClass);
        for (Criterion criterion : criterionList)
        {
            criteria.add(criterion);
        }
        return criteria.list();
    }

    protected String getCanonicalPersistentClassName()
    {
        return persistentClass.getCanonicalName();
    }

    /**
     * Gets the current Hibernate Session object.
     * 
     * @return
     */
    protected Session getCurrentSession()
    {
        return sessionFactory.getCurrentSession();
    }

    /*
     * This method only provided for interface compatibility.  Not recommended for use with large batches 
     * (this is an inefficient implementation, and it's somewhat difficult to perform batch operations with Hibernate).
     * 
     * (non-Javadoc)
     * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#batchInsert(java.util.Collection)
     */
    @Override
    public int[] batchInsert(final Collection<T> entityCollection)
    {
        int[] updateCounts = new int[entityCollection.size()];
        int i = 0;
        for (T entity : entityCollection)
        {
            try
            {
                saveOrUpdate(entity);
                updateCounts[i] = 1;
                i++;
            }
            catch (Exception ex)
            {
                clear();
                throw new RuntimeException(ex);
            }
        }
        flush();
        clear();

        return updateCounts;
    }

    /*
     * This method only provided for interface compatibility.  Not recommended for use with large batches 
     * (this is an inefficient implementation, and it's somewhat difficult to perform batch operations with Hibernate).
     * 
     * (non-Javadoc)
     * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#batchUpdate(java.util.Collection)
     */
    @Override
    public int[] batchUpdate(final Collection<T> entityCollection)
    {
        return batchInsert(entityCollection);
    }

    /**
     * Completely clear the session. Evict all loaded instances and cancel all pending saves, updates and deletions. Do
     * not close open iterators or instances of ScrollableResults.
     */
    public void clear()
    {
        getCurrentSession().clear();
    }

    /*
     * (non-Javadoc)
     * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#delete(gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity)
     */
    @Override
    public void delete(final T persistentObject)
    {
        getCurrentSession().delete(persistentObject);
    }

    /*
     * (non-Javadoc)
     * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#findAll()
     */
    @Override
    public List<T> findAll()
    {
        return getCurrentSession().createQuery("from " + persistentClass.getName()).list();
    }

    /**
     * Finds a collection of entity objects which match to the example instance, minus any specified properties which should be excluded from the matching.
     * 
     * @param exampleInstance
     * @param excludeProperty
     * @return
     */
    public List<T> findByExample(final T exampleInstance,
                                 final String[] excludeProperty)
    {
        Criteria criteria = getCurrentSession().createCriteria(persistentClass);
        Example example = Example.create(exampleInstance);
        if (excludeProperty != null)
        {
            for (String exclude : excludeProperty)
            {
                example.excludeProperty(exclude);
            }
        }
        criteria.add(example);
        return criteria.list();
    }

    /*
     * (non-Javadoc)
     * @see com.sun.cloud.lifecycle.core.persistence.dao.GenericDao#findById(java.io.Serializable)
     */
    @Override
    public T findById(final PK id)
    {
        return (T) getCurrentSession().load(persistentClass, id);
    }

    /**
     * Force this session to flush. Must be called at the end of a unit of work, before commiting the transaction and
     * closing the session (depending on flush-mode, Transaction.commit() calls this method).
     * 
     * Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.
     */
    public void flush()
    {
        getCurrentSession().flush();
    }

    /*
     * (non-Javadoc)
     * @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#saveOrUpdate(gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity)
     */
    @Override
    public T saveOrUpdate(final T entity)
    {
        try
        {
            entity.setUpdatedDate(new Date());
            getCurrentSession().saveOrUpdate(entity);
            return entity;
        }
        catch (Exception ex)
        {
            String errorMessage = "Failed to save the object.";
            log.error(errorMessage, ex);
            throw new RuntimeException(errorMessage, ex);
        }
    }

    /**
     * Setter for the persistentClass property.
     * 
     * @param persistentClass
     */
    public void setPersistentClass(final Class<T> persistentClass)
    {
        this.persistentClass = persistentClass;
    }

    /**
     * Property setter.
     * 
     * @param sessionFactory
     */
    public void setSessionFactory(final SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

}

애플리케이션은 애플리케이션 컨텍스트에서 DAO를 가져옵니다.

// load the Spring application context, get the DAOs
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] { "dailyAveragingApplicationContext.xml" });
esrlDailyAvgDao = (EsrlDailyAvgDao) applicationContext.getBean("esrlDailyAvgDao");
esrlObservationsDao = (EsrlObservationsDao) applicationContext.getBean("esrlObservationsDao");

엔터티를 저장하려고 하면 예외가 발생합니다.

esrlDailyAvgDao.saveOrUpdate(esrlDailyAvg);

DAO 클래스 자체는 트랜잭션 주석을 사용합니다.

@Transactional
public class EsrlDailyAvgDaoHibernateImpl
    extends GenericDaoHibernateImpl<EsrlDailyAvg, Long>
    implements EsrlDailyAvgDao

예외 스택 추적은 다음과 같습니다.

SEVERE: Failed to save the object.
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
    at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.getCurrentSession(GenericDaoHibernateImpl.java:56)
    at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.saveOrUpdate(GenericDaoHibernateImpl.java:187)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
    at $Proxy19.saveOrUpdate(Unknown Source)
    at gov.noaa.ncdc.cmb.esrl.ingest.EsrlDailyAvgProcessor.main(EsrlDailyAvgProcessor.java:469)

는 했습니다를 했습니다.@Transactional/generic Hibernate DAO스하는 DAO된 saveOrUpdate()스)에,하는@Transactional메서드를 구현하는 실제 클래스에 지정해야 합니다.은 제가 d을 선언한다면 입니다.@Transactional차일드 클래스에서는 차일드 클래스에 의해 상속되는 모든 메소드를 포함했습니다.은인 것 .@Transactional주석은 클래스 내에서 구현된 메서드에만 적용되고 클래스에서 상속된 메서드에는 적용되지 않습니다.

다음 오류가 발생했습니다.

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)

최대 절전 모드 속성 파일을 변경하여 이 문제를 해결했습니다.

hibernate.current_session_context_class=thread

나의 코드와 구성 파일은 다음과 같습니다.

session =  getHibernateTemplate().getSessionFactory().getCurrentSession();

session.beginTransaction();

session.createQuery(Qry).executeUpdate();

session.getTransaction().commit();

속성 파일에

hibernate.dialect=org.hibernate.dialect.MySQLDialect

hibernate.show_sql=true

hibernate.query_factory_class=org.hibernate.hql.ast.ASTQueryTranslatorFactory

hibernate.current_session_context_class=thread

구성 파일에

<properties>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>         
<prop key="hibernate.query.factory_class">${hibernate.query_factory_class}</prop>       
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.current_session_context_class">${hibernate.current_session_context_class}</prop>
</props>
</property>
</properties>

요.

속성을 추가한 후:

<prop key="hibernate.current_session_context_class">thread</prop>다음과 같은 예외가 있습니다.

org.hibernate.HibernateException: createQuery is not valid without active transaction
org.hibernate.HibernateException: save is not valid without active transaction.

그래서 저는 그 재산을 정하는 것은 좋은 해결책이 아니라고 생각합니다.

마지막으로 "스레드에 바인딩된 최대 절전 모드 세션 없음" 문제를 해결합니다.

1.<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
2.추가하다<tx:annotation-driven />xml servlett.xml에는 dispatcher-servlet.xml합니다가는됩니다.
합니다. @서비스 및 @Repository 다음에 @Transactional 을 추가합니다.

저도 오늘 같은 문제가 있었습니다.여기서 해결책을 찾는 동안,제가 수입하는 대신에 바보같은 실수를 했습니다.

import org.springframework.transaction.annotation.Transactional;

나도 모르게 수입을 했습니다.

import javax.transaction.Transactional;

변경 후 모든 것이 잘 되었습니다.

그래서 누군가가 같은 실수를 한다면, 공유하는 것을 생각해 봅니다.

가지고 계십니까?org.springframework.orm.hibernate3.support.OpenSessionInViewFilter웹앱에서 구성됨web.xml(응용프로그램이 웹앱임을 assuming) 또는 그에 따라 통화를 포장하시겠습니까?

당신이 아래의 오류에 직면하게 될 때는 언제든지 그것을 따르세요.

오르간 hibern동면예외:스레드에 바인딩된 최대 절전 모드 세션이 없으며 구성에서는 여기서 org.springframework.orm.hibernate3에 트랜잭션이 아닌 세션을 생성할 수 없습니다.SpringSessionContext.currentSession(SpringSessionContext.java:63)

퍼팅 a@Transactional수업을 구현하는 각 방법에 대한 주석.

공유 기능 내부에서 동일한 오류가 발생했지만, 이 공유 기능에 대한 일부 호출에 대해서만 발생했습니다.저는 결국 공유 기능을 호출하는 클래스 중 하나가 작업 단위 안에 포장하지 않는다는 것을 깨달았습니다.작업 단위로 이 클래스 기능을 업데이트하면 모든 것이 예상대로 작동했습니다.

따라서 이와 같은 오류가 발생하지만 승인된 답변이 적용되지 않는 미래의 방문자를 위해 이 글을 게시하십시오.

당신이 그립습니다<context:annotation-config />주석이 스캔되지 않도록 스프링 컨텍스트에서 확인할 수 있습니다.

자식 클래스에서 @Transactional을 사용할 수 있지만, 각 메서드를 재정의하고 슈퍼 메서드를 호출해야 작동할 수 있습니다.

예:

@Transactional(readOnly = true)
public class Bob<SomeClass> {
   @Override
   public SomeClass getValue() {
       return super.getValue();
   }
}

이를 통해 필요한 각 메서드에 대해 설정할 수 있습니다.

언급URL : https://stackoverflow.com/questions/4961636/no-hibernate-session-bound-to-thread-and-configuration-does-not-allow-creation

반응형