Pregunta

Estoy tratando de configurar mi proyecto usando Spring 3.1 y Hibernate 4. He estado siguiendo algunos tutoriales en línea. Recibo un error extraño que, según los foros de primavera, debería haberse arreglado con Spring 3.1. Rastreador de insectos de primavera

Cuando mi servicio llama getCurrentSession(), arroja la siguiente excepción:

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)

**** EDITAR: Actualizó mi primavera-dao.xml de acuerdo con la primavera Documentación de primavera 3.1 para transacciones. He intentado cambiar mi fuente de datos con un org.apache.commons.dbcp.basicdataSource. ¿Hay alguna propiedad que me falte en mi configuración que pueda estar causando esto? ****

Aquí está mi primavera-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" />

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

Y finalmente mi servicio ...

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

Me doy cuenta de que mi fuente de datos probablemente no se está acostumbrando. Si he olvidado incluir cualquier configuración, puedo actualizar esta publicación. Además, si se necesitan los registros de inicio de Tomcat, también puedo proporcionarlos.

¿Fue útil?

Solución

Tuve este problema con Spring-4.0.6 y Hibernate-4.3.6.

La solución es mover todas las directivas basadas en la anotación, escaneos de componentes, basadas en anotaciones de root-Context.xml a servlet-Context.xml:

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

DataSource, SessionFactory y TransactionManager aún se pueden definir en root-Context.xml.

Otros consejos

Tengo el mismo problema en una aplicación web. El problema es con el cual existe en ambos archivos de configuración: application-context.xml y webMVC-Context.xml. WebMVC-Context.xml se carga después de la aplicación-Context.xml. Creo que la clase DAO se carga primero con referencias transaccionales cuando la aplicación-Context.xml está cargada, pero se reemplaza con otro objeto, sin referencias transaccionales, cuando se carga webMVC-Context.xml. De cualquier manera, resuelvo el problema con paquetes específicos escaneados:
<context:component-scan base-package="com.app.repository" />
para la aplicación-Context.xml y
<context:component-scan base-package="com.app.web" />
para webMVC-Context.xml.

¿Es una aplicación web? Si es así, considere usar OpenSessionInviewFilter. Porque creo que al usar Currentsession (que está vinculado al hilo actual) debe haber un punto en el código que desaire la sesión del hilo.

No estoy seguro de si Transaction Manager hace esto o no.

Tuve el mismo error que el tuyo.

Este es un error que aún no se ha resuelto.

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

Intente cambiar los archivos JAR de Hibernate a 3.6. Porque la primavera lo usa.

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

aquí la primavera 3.1 artefactos y dependencias

Como se indica en Referencia de primavera (3.2.x):

En el marco de MVC web, cada despacheteServlet tiene su propio WebApplicationContext, que hereda todos los frijoles ya definidos en Root WebApplicationContext. Estos frijoles heredados se pueden anular en el alcance específico del servlet, y puede definir nuevos frijoles específicos de alcance locales en una instancia de servlet dada.

Entonces los frijoles definidos o escaneados con <context:component-scan> será visible en sus controladores para que pueda @auTowired, pero no será visible en otros archivos de aplicación de aplicaciones*, por lo que a menos que <tx:annotation-driven/> no se ha definido en la configuración de DispatcherServlet, @Transactional no funcionará.

Así que supongo que probablemente tengas un <context:component-scan> en la configuración de su desplazamiento y <tx:annotation-driven/> Declaración en su ApplicationContext*.xml, entonces @Autowired funciona bien, pero @Transactional no es.

Tuve el mismo problema y probé todas las soluciones respondidas. La respuesta de Vali fue muy útil. Lo que funcionó para mí fue mover estos frijoles de ApplicationContext.xml a 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>

Además, debe agregar en 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
    "

Agregue un filtro OpenSessionInviewFilter en su 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>

No estoy seguro, pero el problema podría estar en p:packagesToScan. Su ConfigurationUserService está en paquete com.foo.lystra.services pero p:packagesToScan posee com.foo.lystra.beans

Su configuración no apunta a las clases anotadas. Agregalos

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

Esto es similar a AnotationsessionFactoryBean que estaba allí antes. Revise la API aquí .

Creo que necesitas:

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

De lo contrario, el contexto de primavera no encontrará su servicio, por lo que no envolverá sus métodos con los aspectos transaccionales.

Tenía exactamente el mismo error y se resolvió simplemente creando un interfaz para mi servicio. Entonces, en tu caso, crearía:

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

Luego cambie CongregationUserService para implementarlo:

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

Y donde realizó auto -CongregationUserService, Autowire icongregationUserService en su lugar:

@Autowired
private ICongregationUserService congregationUserService;

Resolví este problema poniendo <tx:annotation-driven transaction-manager="miTransactionManager"/> en el despachador-servlet.xml en lugar de cualquier otro archivo de configuración XML.

Creo que de esta manera permite que los frijoles coexistan en el mismo contexto de primavera.

Descubrí que este problema es un error de primavera

este enlace https://jira.springsource.org/browse/spr-9020 informa el problema.

Para arreglarlo, he usado la solución de Matias Mirabelli que se puede encontrar en este enlace https://gist.github.com/seykron/4770724

Lo que está sucediendo es que los métodos anotados con Propagation.SUPPORTS admite la transacción, pero si no hay transacciones vinculadas al hilo del resorte en lugar de crear una nueva sesión, lanza una HibernateException

Para configurar la sollution, puede usar la propiedad Hibernate:

hibernate.current_session_context_class = com.your.package.TransactionAwareSessionContext

puse

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

Y puse

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

int el servlet-Context.xml.

Funciona.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top