web-dev-qa-db-fra.com

Aucune session trouvée pour le thread actuel (Spring 3.1.X et Hibernate 4)

J'essaie de configurer mon projet avec Spring 3.1 et Hibernate 4. J'ai suivi des tutoriels en ligne. Je reçois une erreur étrange qui, selon Spring, aurait dû être corrigée avec Spring 3.1. Spring Bug Tracker

Lorsque mon service appelle getCurrentSession(), il lève l'exception suivante:

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)

**** EDIT: mis à jour mon fichier spring-dao.xml conformément à la documentation Spring Spring 3.1 pour transactions . J'ai essayé d'échanger ma source de données avec un org.Apache.commons.dbcp.BasicDataSource. Y a-t-il des propriétés qui me manquent dans ma configuration et qui pourraient en être la cause? ****

Voici mon 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" />

Bean My User (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();
}
}

Et enfin mon 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();
}
}

Je me rends compte que ma source de données n'est probablement pas utilisée. Si j'ai oublié d'inclure des configurations, je peux mettre à jour ce post. De plus, si les journaux de démarrage de Tomcat sont nécessaires, je peux également les fournir.

18
It Grunt

J'ai eu ce problème avec spring-4.0.6 et hibernate-4.3.6.

La solution consiste à déplacer toutes les directives basées sur les annotations, l'analyse par composant et les annotations de root-context.xml vers servlet-context.xml:

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

dataSource, sessionFactory et transactionManager peuvent encore être définis dans root-context.xml.

6
user3418209

J'ai le même problème dans une application web. Le problème est de savoir qui existe dans les deux fichiers de configuration: application-context.xml et webmvc-context.xml. Webmvc-context.xml est chargé après application-context.xml. Je pense que la classe DAO est chargée en premier avec des références transactionnelles lorsque le fichier application-context.xml est chargé, mais il est remplacé par un autre objet, sans références transactionnelles, lorsque le fichier webmvc-context.xml est chargé. De toute façon, je résous le problème avec des paquets spécifiques analysés: 
<context:component-scan base-package="com.app.repository" /> 
pour application-context.xml, et 
<context:component-scan base-package="com.app.web" />
pour webmvc-context.xml.

12
Vali

J'ai eu la même erreur que la tienne.

C'est un bug qui n'est pas encore résolu. 

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

Essayez de changer les fichiers JAR hibernés en 3.6. parce que le printemps l'utilise.

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

ici Printemps 3.1 artefact et dépendances

2
erencan

Est-ce une application web? Si c'est le cas, envisagez d'utiliser OpenSessionInViewFilter. Parce que je crois qu'en utilisant currentSession (qui est liée au thread actuel), il doit y avoir un point dans le code qui délie la session du thread.

Je ne suis pas sûr que le gestionnaire de transaction le fasse ou non. 

2
Amir Pashazadeh

Comme indiqué dans Référence de ressort (3.2.x):

Dans l'infrastructure Web MVC, chaque DispatcherServlet a son propre WebApplicationContext, qui hérite de tous les beans déjà définis dans De la racine WebApplicationContext. Ces beans hérités peuvent être Remplacés dans l'étendue spécifique à la servlet et vous pouvez définir de nouveaux beans spécifiques à l'étendue Locaux pour une instance de servlet donnée.

Ainsi, les Beans définis ou analysés avec <context:component-scan> seront visibles dans vos contrôleurs. Vous pourrez donc les autoriser automatiquement, mais ne seront pas visibles dans les autres fichiers applicationContext *. Ainsi, à moins que <tx:annotation-driven/> ne soit défini dans la configuration de DispatcherServlet, @Transactional ne fonctionnera pas.

Je suppose donc que vous avez probablement un <context:component-scan> dans la configuration de votre DispatcherServlet et une déclaration <tx:annotation-driven/> dans votre applicationContext * .xml, donc @Autowired fonctionne bien, mais @Transactional ne fonctionne pas. 

1
Mateusz Szulc

J'ai eu le même problème et testé toutes les solutions répondues. La réponse de Vali était très utile. Ce qui a fonctionné pour moi, c’est de transférer ces beans d’applicationContext.xml vers 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>

En outre, vous devez ajouter dans web-servlet.xml:

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

Ajouter un filtre OpenSessionInViewFilter dans votre web.xml

<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

J'ai résolu ce problème en mettant <tx:annotation-driven transaction-manager="miTransactionManager"/> dans le dispatcher-servlet.xml au lieu de tout autre fichier de configuration XML.

Je pense que cette façon permet aux haricots de coexister dans le même contexte printanier.

0
Dani

J'ai trouvé que cette question est un bug du printemps 

ce lien https://jira.springsource.org/browse/SPR-9020 signale le problème.

pour y remédier, j'ai utilisé la solution de contournement de Matias Mirabelli qui se trouve sur ce lien https://Gist.github.com/seykron/4770724

ce qui se passe, c’est que les méthodes annotées avec Propagation.SUPPORTS prennent en charge la transaction, mais si aucune transaction n'est liée au fil, le ressort au lieu de créer une nouvelle session, il jette une HibernateException

afin de configurer la solution, vous pouvez utiliser la propriété hibernate:

hibernate.current_session_context_class = com.your.package.TransactionAwareSessionContext

0
thiagoh

Avait exactement la même erreur et cela a été résolu en créant simplement une interface pour mon service. Donc dans votre cas, je créerais:

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

puis changez CongregationUserService pour l'implémenter:

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

et si vous avez choisi CongregationUserService, connectez-vous automatiquement à ICongregationUserService:

@Autowired
private ICongregationUserService congregationUserService;
0
Walid

Votre configuration ne pointe pas vers les classes annotées. Ajoutez-les

<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>

C'est similaire à AnnotationSessionFactoryBean qui était là plus tôt. Vérifiez l'API ici .

0
Aravind A

Pas sûr, mais le problème pourrait être dans p:packagesToScan. Votre configurationUserService est dans le paquet com.foo.lystra.services mais p:packagesToScan a com.foo.lystra.beans

0
Gaurav

Je crois que vous avez besoin de:

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

Sinon, le contexte de printemps ne trouvera pas votre service et vos méthodes ne seront donc pas encapsulées dans les aspects transactionnels.

0
jonnysamps

Je mets

<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 le root.xml.

Et je mets

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

int le servlet-context.xml.

Ça marche.

0
陈俊杰