wake-up-neo.com

Keine Sitzung für aktuellen Thread gefunden (Spring 3.1.X und Hibernate 4)

Ich versuche, mein Projekt mit Spring 3.1 und Hibernate 4 einzurichten. Ich habe einige Tutorials online verfolgt. Ich bekomme einen seltsamen Fehler, der laut Spring-Foren mit Spring 3.1 behoben sein sollte. Spring Bug Tracker

Wenn mein Dienst getCurrentSession() aufruft, wird die folgende Ausnahme ausgelöst:

org.hibernate.HibernateException: **No Session found for current thread**] with root cause 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:881)

**** BEARBEITEN: meine spring-dao.xml wurde gemäß Spring Spring 3.1-Dokumentation für Transaktionen aktualisiert. Ich habe versucht, meine Datenquelle mit einer org.Apache.commons.dbcp.BasicDataSource auszutauschen. Gibt es Eigenschaften, die ich in meiner Konfiguration vermisse, die dies verursachen könnten? ****

Hier ist mein spring-dao.xml:

 <!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />   

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="hibernateProperties">
        <value>hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect</value>
    </property>
</bean>

<!-- Declare a datasource that has pooling capabilities-->   
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
            destroy-method="close"
            p:driverClass="${app.jdbc.driverClassName}"
            p:jdbcUrl="${app.jdbc.url}"
            p:user="${app.jdbc.username}"
            p:password="${app.jdbc.password}"
            p:acquireIncrement="5"
            p:idleConnectionTestPeriod="60"
            p:maxPoolSize="100"
            p:maxStatements="50"
            p:minPoolSize="10" />

<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" 
            p:sessionFactory-ref="sessionFactory" />

Meine User-Bean (User.Java)

package com.foo.lystra.beans;

import Java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="users")
public class User implements Serializable {
private static final long serialVersionUID = -5527566191402296042L;

@Id
@Column(name = "idusers")
private Integer user_id;

@Column(name="login_name")
private String loginName;

@Column(name="password")
private String password;

@Column(name="role")
private String role;

@Column(name="congregation_id")
private Integer congregation_id;

public Integer getUser_id() {
    return user_id;
}
public void setUser_id(Integer user_id) {
    this.user_id = user_id;
}
public String getLoginName() {
    return loginName;
}
public void setLoginName(String loginName) {
    this.loginName = loginName;
}
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}
public String getRole() {
    return role;
}
public void setRole(String role) {
    this.role = role;
}
public Integer getCongregation_id() {
    return congregation_id;
}
public void setCongregation_id(Integer congregation_id) {
    this.congregation_id = congregation_id;
}

public String toString() {
    return "user_name: " + this.loginName + " congregation_id: " + this.congregation_id.toString();
}
}

Und zum Schluss mein Service ...

package com.foo.lystra.services;

import Java.util.List;

import javax.annotation.Resource;

import org.Apache.commons.logging.LogFactory;
import org.Apache.commons.logging.Log;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.foo.lystra.beans.User;
import com.foo.lystra.beans.Congregation;

@Service("congregationUserService")
@Transactional
public class CongregationUserService {
protected static Log logger = LogFactory.getLog(CongregationUserService.class);

@Resource(name="sessionFactory")
private SessionFactory sessionFactory;

public List<User> getAllUsers() {
    logger.debug("getting all users");

            //Exception is thrown on this next line:
    Session session = sessionFactory.getCurrentSession();

    Query query = session.createQuery("FROM users");
    return query.list();
}
}

Ich stelle fest, dass meine Datenquelle wahrscheinlich nicht verwendet wird. Wenn ich vergessen habe, Konfigurationen hinzuzufügen, kann ich diesen Beitrag aktualisieren. Wenn die Tomcat-Startprotokolle benötigt werden, kann ich sie auch bereitstellen.

18
It Grunt

Ich hatte dieses Problem mit Spring-4.0.6 und Hibernate-4.3.6.

Die Lösung besteht darin, alle annotationsgesteuerten, durch Komponenten gescannten, annotationsgesteuerten Direktiven von root-context.xml nach servlet-context.xml zu verschieben:

<mvc:annotation-driven />
<context:component-scan base-package="ru.dd.demo" />
<tx:annotation-driven transaction-manager="transactionManager" />

dataSource, sessionFactory und transactionManager können noch in root-context.xml definiert werden.

6
user3418209

Ich habe das gleiche Problem in einer Webanwendung. Das Problem ist, mit dem beide Konfigurationsdateien vorhanden sind: application-context.xml und webmvc-context.xml. Die webmvc-context.xml wird nach application-context.xml geladen. Ich denke, dass die DAO-Klasse zuerst mit Transaktionsverweisen geladen wird, wenn die Datei application-context.xml geladen wird. Sie wird jedoch durch ein anderes Objekt ohne Transaktionsverweise ersetzt, wenn webmvc-context.xml geladen wird. Ich löse das Problem auf jeden Fall mit bestimmten gescannten Paketen: 
<context:component-scan base-package="com.app.repository" /> 
für application-context.xml und 
<context:component-scan base-package="com.app.web" />
für webmvc-context.xml.

12
Vali

Ich hatte den gleichen Fehler wie du.

Dies ist ein Fehler, der noch nicht behoben wurde. 

https://jira.springsource.org/browse/SPR-9028

Versuchen Sie, die Hibernate-JAR-Dateien in 3.6 zu ändern. weil der Frühling es benutzt.

http://mvnrepository.com/artifact/org.springframework/spring-orm/3.1.0.RELEASE

hier Spring 3.1 Artefakte und Abhängigkeiten

2
erencan

Ist es eine Webanwendung? Wenn dies der Fall ist, sollten Sie OpenSessionInViewFilter verwenden. Ich glaube, bei der Verwendung von currentSession (die an den aktuellen Thread gebunden ist) muss im Code ein Punkt vorhanden sein, der die Sitzung vom Thread löst.

Ich bin nicht sicher, ob der Transaktionsmanager dies tut oder nicht. 

2
Amir Pashazadeh

Wie in Spring Reference (3.2.x) angegeben:

Im Web-MVC-Framework verfügt jedes DispatcherServlet über einen eigenen WebApplicationContext, der alle bereits in Definierten Beans, den Root-WebApplicationContext, erbt. Diese vererbten Beans können Im servletspezifischen Bereich überschrieben werden, und Sie können neue Anwendungsspezifische Beans definieren, die für eine bestimmte Servlet-Instanz lokal sind.

Mit <context:component-scan> definierte oder gescannte Beans sind also in Ihren Steuerungen sichtbar. Sie können sie also @Autowired verwenden, sind jedoch in anderen applicationContext * -Dateien nicht sichtbar. Wenn also <tx:annotation-driven/> nicht in der Konfiguration von DispatcherServlet definiert wurde, @Transactional funktioniert nicht.

Ich vermute also, dass Sie wahrscheinlich einen <context:component-scan> in der config und <tx:annotation-driven/>-Deklaration Ihres DispatcherServlets in Ihrem applicationContext * .xml haben, also @Autowired funktioniert, aber @Transactional nicht. 

1
Mateusz Szulc

Ich hatte das gleiche Problem und testete alle beantworteten Lösungen. Valis Antwort war sehr hilfreich. Was für mich funktionierte, war das Verschieben dieser Beans aus applicationContext.xml in web-servlet.xml:

<bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>       
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

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

Außerdem müssen Sie in web-servlet.xml Folgendes hinzufügen:

xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"

xsi:schemaLocation="       
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    "
1
Adrian Cosma

Fügen Sie einen OpenSessionInViewFilter-Filter in Ihrer web.xml hinzu

<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name>
        <param-value>sessionFactory</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>
1
punseti

Ich habe dieses Problem gelöst, indem Sie <tx:annotation-driven transaction-manager="miTransactionManager"/> in die Datei dispatcher-servlet.xml anstelle einer anderen XML-Konfigurationsdatei eingefügt haben.

Ich denke, auf diese Weise können Bohnen im selben Frühlingskontext koexistieren.

0
Dani

Ich habe festgestellt, dass dieses Problem ein Frühlingsproblem ist 

dieser link https://jira.springsource.org/browse/SPR-9020 meldet das problem ..

um dies zu beheben, habe ich die Problemumgehung von Matias Mirabelli verwendet, die auf diesem Link zu finden ist https://Gist.github.com/seykron/4770724

was geschieht, ist, dass mit Propagation.SUPPORTS kommentierte Methoden die Transaktion unterstützen, aber wenn keine Transaktionen an den Thread gebunden sind, anstatt eine neue Sitzung zu erstellen, wird eine HibernateException ausgegeben.

um die Sollution zu konfigurieren, können Sie die Hibernate-Eigenschaft verwenden:

hibernate.current_session_context_class = com.your.package.TransactionAwareSessionContext

0
thiagoh

Hatte genau den gleichen Fehler und es wurde gelöst, indem einfach eine Schnittstelle für meinen Dienst erstellt wurde. In Ihrem Fall würde ich also Folgendes schaffen:

public interface ICongregationUserService {
   public List<User> getAllUsers();
}

Ändern Sie dann CongregationUserService, um es zu implementieren:

@Service("congregationUserService")
@Transactional
public class CongregationUserService implements ICongregationUserService{
   //...
}

und wo Sie automatisch CongregationUserService eingestellt haben, stattdessen ICongregationUserService automatisch:

@Autowired
private ICongregationUserService congregationUserService;
0
Walid

Ihre Konfiguration verweist nicht auf die kommentierten Klassen. Füge sie hinzu

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
  <property name="hibernateProperties">
     <value>hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect</value>
  </property>

  <property name="annotatedClasses">
    <list>
      <value>test.package.Foo</value>
      <value>test.package.Bar</value>
    </list>
  </property>
</bean>

Es ist ähnlich zu AnnotationSessionFactoryBean , das zuvor dort war. Überprüfen Sie die API hier .

0
Aravind A

Nicht sicher, aber das Problem könnte in p:packagesToScan liegen. Ihr ConfigurationUserService befindet sich im Paket com.foo.lystra.services, aber p:packagesToScan hat com.foo.lystra.beans

0
Gaurav

Ich glaube, du brauchst:

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

Andernfalls wird der Frühlingskontext Ihren Service nicht finden. Daher werden Ihre Methoden nicht mit den Transaktionsaspekten verknüpft.

0
jonnysamps

Ich setze

<context:component-scan base-package="com.sprhib.repo"/>  #(some class files are annotaed by @Repository,@Service,@Component)
<tx:annotation-driven transaction-manager="txManager" />
<task:annotation-driven/>

int die root.xml.

Und ich stelle

<context:component-scan base-package="com.sprhib.web"/>  #(some class files are annotaed by @Controller)
<mvc:annotation-driven />

int die servlet-context.xml.

Es klappt.

0
陈俊杰