0

コードを使用する場合、トランザクションでMaven + Spring 3.1 + Spring MVC 3.1 + Hibernate 4.1で構築されたプロジェクトを作成しました。

Session session=sessionFactory.getCurrentSession();
session.save(user);

getCurrentSession() で例外が発生します。

SEVERE: Servlet.service() for servlet appServlet threw exception
org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1024)
    at com.company.cv.dao.UserDAO.saveUser(UserDAO.java:30)
    at com.company.cv.service.UserService.saveUser(UserService.java:20)
    at com.company.cv.HomeController.saveUser(HomeController.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)

しかし、getCurrentSession の代わりに openSession を使用すると、例外は発生せず、コード トランザクションは正常に完了します。

    Session session = sessionFactory.openSession();
    session.save(user);

理由は何ですか?助けてくれてありがとう

私のapplicationContext.xml:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/companycv" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="annotatedClasses">
    <list>
        <value>com.company.cv.model.User</value>
    </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

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

サーブレット-context.xml:

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

<context:component-scan base-package="com.company.cv" />

私のサービスコード:

@Service
public class UserService implements UserServiceIntf{

    @Autowired
    UserDAOIntf userDAO;

    @Transactional
    public void saveUser(User user) {
        userDAO.saveUser(user);
    }
}

私のDAOコード:

@Repository
public class UserDAO implements UserDAOIntf {

    @Autowired
    SessionFactory sessionFactory;

    public void saveUser(User user) {
        Session session=sessionFactory.getCurrentSession();
        session.save(user);
    }
}
4

3 に答える 3

1

@TransactionalDAO メソッドを呼び出すサービス メソッドの上に注釈を追加する必要がありますsave。また、txManagerアプリのコンテキストで定義したため、トランザクションを手動で管理する必要はありません。

于 2012-09-14T23:49:35.877 に答える
1

あなたが間違っていると私が観察したことの 1 つは、Hibernate トランザクション API の使用法と Spring 管理のトランザクション管理抽象化を混在させていることです。これは厳密にはお勧めできません。

Session session=sessionFactory.getCurrentSession();
Transaction tx=session.beginTransaction(); // This is using Hibernate transaction API
session.save(user);
sessionFactory.getCurrentSession().save(user);
tx.commit();// This is using Hibernate transaction API

上記のコードでは、hibernate トランザクション API を使用して、Spring トランザクション管理と共にトランザクションを管理しています (サービス メソッドにトランザクション アノテーションを付ける場合)。

これだけ使えばいい

Session session=sessionFactory.getCurrentSession();
session.save(user);
sessionFactory.getCurrentSession().save(user);

また、他の人が指摘したように、データソース定義が重複してリストされています。そして、Spring を介して注入されるため意味をなさない sessionFactory を取得できないと言い、他の場合には sessionFactory にアクセスできると言いました。これが発生する理由はありません。

アップデート

したがって、両方の場合で sessionFactory にアクセスできると言っていますが、getCurrentSession の場合は機能しません。提案されたすべての変更を行った後、log4j 構成 (log4j を使用している場合) で Hibernate ロギングと Spring フレームワーク ロギングを有効にして、内部で何が起こっているかを確認することをお勧めします。関連するアクティビティを追跡します。

log4j 構成ファイルは次のようになります

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=<file-path>
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n


# Root logger
log4j.rootLogger=INFO, file

# Hibernate and Spring logging
log4j.logger.org.hibernate=DEBUG
log4j.logger.org.springframework.transaction=DEBUG

これにより、明確なイメージが得られます。

于 2012-09-16T15:24:22.697 に答える