Domanda

Sto cercando di impostare il mio progetto utilizzando Spring 3.1 e Hibernate 4.Ho seguito alcuni tutorial online.Ricevo uno strano errore che secondo i forum di Spring avrebbe dovuto essere risolto con Spring 3.1. Localizzatore di insetti primaverili

Quando il mio servizio chiama getCurrentSession(), genera la seguente eccezione:

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)

****MODIFICARE:aggiornato il mio spring-dao.xml in base a Spring Primavera 3.1 Documentazione per le transazioni.Ho provato a sostituire la mia origine dati con un org.apache.commons.dbcp.BasicDataSource.Ci sono proprietà che mi mancano nella mia configurazione che potrebbero causare questo?****

Ecco il mio 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" />

Il mio bean utente (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();
}
}

E infine il mio servizio...

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

Mi rendo conto che probabilmente la mia origine dati non viene utilizzata.Se ho dimenticato di includere eventuali configurazioni posso aggiornare questo post.Inoltre, se sono necessari i registri di avvio di Tomcat, posso fornirli anch'io.

È stato utile?

Soluzione

Ho avuto questo problema con Spring-4.0.6 e Hibernate-4.3.6.

La soluzione è spostare tutte le direttive basate sull'annotazione, scansione componente, guidate da annotazioni da root-conftext.xml a servlet-conftext.xml:

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

DataSource, SessionFactory e TransactionManager possono essere ancora definiti su Root-Context.xml.

Altri suggerimenti

Ho lo stesso problema in un'applicazione Web. Il problema è con cui esistono in entrambi i file di configurazione: application-context.xml e webmvc-conftext.xml. WebMVC-Context.xml viene caricato dopo l'applicazione-context.xml. Penso che la classe DAO sia caricata per prima con riferimenti transazionali quando viene caricato l'applicazione-conftext.xml, ma è sostituita con un altro oggetto, senza riferimenti transazionali, quando viene caricato WebMVC-CONTETT.XML. In ogni caso, risolvo il problema con pacchetti specifici scansionati:
<context:component-scan base-package="com.app.repository" />
per application-context.xml e
<context:component-scan base-package="com.app.web" />
Per WebMVC-Context.xml.

È un'applicazione web? In tal caso, considera l'utilizzo di OpenSessionInViewFilter. Perché credo che quando si utilizzano la correntessione (che è legata al thread corrente) ci deve essere un punto nel codice che si schiera la sessione dal thread.

Non sono sicuro che il gestore delle transazioni lo faccia o no.

Ho avuto lo stesso errore del tuo.

Questo è un bug che non è ancora risolto.

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

Prova a modificare i file JAR di Hibernate in 3.6. Perché la primavera lo usa.

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

Qui primavera 3.1 artefatto e dipendenze

Come affermato in Riferimento primaverile (3.2.x):

Nel framework Web MVC, ogni Dispatcherservlet ha il suo WebApplicationContext, che eredita tutti i fagioli già definiti nel root WebApplicationContext. Questi fagioli ereditari possono essere sovrascritti nell'ambito specifico del servlet e è possibile definire i nuovi fagioli specifici dell'ambito locale a una determinata istanza di servlet.

Quindi i fagioli definiti o scansionati <context:component-scan> sarà visibile nei tuoi controller in modo da poterli @autowowirarli, ma non sarà visibile in altri file di applicazione*, quindi a meno che <tx:annotation-driven/> non è stato definito nella configurazione di dispatcherservlet, @Transactional non funzionerà.

Quindi immagino che probabilmente tu abbia un <context:component-scan> nella configurazione del tuo dispatcherservlet e <tx:annotation-driven/> Dichiarazione in You ApplicationContext*.xml, quindi @Autowired Funziona bene, ma @Transactional non è.

Ho avuto lo stesso problema e ho testato tutte le soluzioni risposte. La risposta di Vali è stata molto utile. Ciò che ha funzionato per me è stato spostare questi fagioli da 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>

Inoltre, è necessario aggiungere 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
    "

Aggiungi un filtro OpenSessionInViewFilter nel tuo 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>

Non sono sicuro, ma il problema potrebbe essere dentro p:packagesToScan. Il tuo servizio di configurazione è in pacchetto com.foo.lystra.services ma p:packagesToScan ha com.foo.lystra.beans

La configurazione non punta alle classi annotate. Aggiungili

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

È simile a Annotazioni. FactoryBean che era lì prima. Controlla l'API qui .

Credo che tu abbia bisogno di:

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

Altrimenti il ​​contesto primaverile non troverà il tuo servizio, quindi non avvolgerà i tuoi metodi con gli aspetti transazionali.

Aveva esattamente lo stesso errore ed è stato risolto semplicemente creando un interfaccia per il mio servizio. Quindi nel tuo caso, creerei:

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

quindi modificare la congregazione Userservice per implementarlo:

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

e dove hai autowowid CongregationUserService, AutoWire IconGregationSerservice: invece:

@Autowired
private ICongregationUserService congregationUserService;

Ho risolto questo problema mettendo <tx:annotation-driven transaction-manager="miTransactionManager"/> In Dispatcher-Servlet.xml invece di qualsiasi altro file di configurazione XML.

Penso che in questo modo consenta ai fagioli di coesistere nello stesso contesto di primavera.

Ho scoperto che questo problema è un bug di primavera

questo link https://jira.springsource.org/browse/spr-9020 riporta il problema ..

Per risolverlo ho usato la soluzione alternativa di Matias Mirabelli che può essere trovata su questo link https://gist.github.com/seykron/4770724

Quello che sta accadendo è che i metodi sono annotati Propagation.SUPPORTS supporta la transazione ma se non ci sono transazioni legate al thread la molla invece di creare una nuova sessione, lancia un HibernateException

Per configurare il sollievo è possibile utilizzare la proprietà Hibernate:

hibernate.current_session_context_class = com.your.package.TransactionAwareSessionContext

metto

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

E ho messo

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

int il servlet-conftext.xml.

Funziona.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top