sesiones - spring mvc ejemplo
Spring Hibernate: no se pudo obtener la sesión sincronizada por transacción para el hilo actual (12)
Creé una aplicación con spring + hibernate, pero siempre obtengo este error. Esta es mi primera aplicación con hibernación, leo algunas guías pero no puedo resolver este problema. ¿Dónde estoy haciendo mal?
Este es el código de mi aplicación
ott 05, 2014 4:03:06 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
Informazioni: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1eab16b: startup date [Sun Oct 05 16:03:06 CEST 2014]; root of context hierarchy
ott 05, 2014 4:03:06 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
Informazioni: Loading XML bean definitions from class path resource [springConfig.xml]
ott 05, 2014 4:03:08 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
ott 05, 2014 4:03:08 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.6.Final}
ott 05, 2014 4:03:08 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
ott 05, 2014 4:03:08 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
ott 05, 2014 4:03:09 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
ott 05, 2014 4:03:09 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
ott 05, 2014 4:03:09 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Exception in thread "main" org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at coreservlets.StudentDAOImpl.create(StudentDAOImpl.java:19)
at coreservlets.MainApp.main(MainApp.java:14)
student.java
package coreservlets;
public class Student {
private Integer id;
private String name;
private Integer age;
public Integer getId(){return id;}//getId
public void setId(Integer id){this.id=id;}//setId
public String getName(){return name;}//getName
public void setName(String name){this.name=name;}//setName
public Integer getAge(){return age;}//getAge
public void setAge(Integer age){this.age=age;}//setAge
}//Student
studentDAO.java
package coreservlets;
import org.hibernate.SessionFactory;
public interface StudentDAO {
public void setSessionFactory(SessionFactory sessionFactory);
public void create(String name,Integer age);
}//StudentDAO
StudentDAOImpl.java
package coreservlets;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class StudentDAOImpl implements StudentDAO {
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory=sessionFactory;
}//setSessionFactory
public void create(String name,Integer age){
Session session=sessionFactory.getCurrentSession();
Student student=new Student();
student.setName(name);
student.setAge(age);
session.save(student);
}//create
}//StudentDAOImpl
MainApp.java
package coreservlets;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("springConfig.xml");
StudentDAOImpl student=(StudentDAOImpl) context.getBean("studentDAOImpl");
student.create("Alessandro", new Integer(33));
}//main
}//MainApp
springConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<context:annotation-config/>
<context:component-scan base-package="coreservlets"/>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_hibernate"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
<property name="initialSize" value="5"/>
<property name="maxTotal" value="10"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
</value>
</property>
</bean>
</beans>
sql
create table student
(
id integer not null auto_increment,
name varchar(20) not null,
age integer not null,
primary key(id)
);
¡Agregué estas configuraciones en web.xml y me funciona bien!
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Además, la respuesta más clasificada me da pistas para evitar que la aplicación entre en pánico en la primera ejecución.
@Transactional = javax.transaction.Transactional ponlo justo al lado de @Repository
Añada transaction-manager
a su <annotation-driven/>
en spring-servlet.xml:
<tx:annotation-driven transaction-manager="yourTransactionBeanID"/>
Agregue la anotación @Transactional de la primavera en el servicio de la clase
Debe habilitar el soporte de transacción ( <tx:annotation-driven>
@EnableTransactionManagement
<tx:annotation-driven>
o @EnableTransactionManagement
) y declarar el transactionManager
y debería funcionar a través de SessionFactory
.
Debes agregar @Transactional
en tu @Repository
Con @Transactional
en @Repository
Spring puede aplicar soporte transaccional en su repositorio.
Su clase de Student
no tiene las anotaciones de @javax.persistence. * Cómo @Entity
, @Entity
que la Configuración de Mapeo para esa clase se ha definido a través de XML.
En tu xyz.DAOImpl.java
Haga los siguientes pasos:
// Paso-1: establecer sesión de fábrica
@Resource(name="sessionFactory")
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf)
{
this.sessionFactory = sf;
}
// Paso-2: intente obtener la sesión actual y capture la excepción HibernateException.
// Paso-3: Si hay alguna excepción HibernateException, entonces verdadero para obtener openSession.
try
{
//Step-2: Implementation
session = sessionFactory.getCurrentSession();
}
catch (HibernateException e)
{
//Step-3: Implementation
session = sessionFactory.openSession();
}
Encontré el mismo problema y finalmente descubrí que no estaba definido en el [dispatcher] -servlet.xml donde el elemento component-scan habilitó @service clase anotada.
Simplemente coloque el elemento de escaneo de componentes juntos, el problema desapareció.
He tenido el mismo problema, pero en una clase que no era parte de la capa de servicio. En mi caso, el administrador de transacciones simplemente se obtuvo del contexto mediante el método getBean()
, y la clase pertenecía a la capa de vista; mi proyecto utiliza la técnica OpenSessionInView
.
El método sessionFactory.getCurrentSession()
ha estado causando la misma excepción que el del autor. La solución para mí fue bastante simple.
Session session;
try {
session = sessionFactory.getCurrentSession();
} catch (HibernateException e) {
session = sessionFactory.openSession();
}
Si el método getCurrentSession()
falla, la openSession()
debería hacer el truco.
Mi configuración fue así. Tuve QuartzJob , Service Bean y Dao. como de costumbre, se configuró con LocalSessionFactoryBean (para hibernación) y SchedulerFactoryBean para Quartz framework. mientras escribía el trabajo de Quartz, por error lo anoté con @ Service , no debería haberlo hecho porque estaba usando otra estrategia para conectar el QuartzBean usando AutowiringSpringBeanJobFactory extendiendo SpringBeanJobFactory .
Entonces, lo que en realidad estaba sucediendo es que gracias a Quartz Autowire, TX se inyectaba a Job Bean y al mismo tiempo se configuraba Tx Context en virtud de la anotación @ Service y, por lo tanto, el TX se estaba desbalanceando.
Espero que ayude a aquellos para quienes las soluciones anteriores realmente no resolvieron el problema. Estaba usando Spring 4.2.5 e Hibernate 4.0.1,
Veo que en este hilo hay una sugerencia innecesaria para agregar la anotación @ Transactional al DAO (@ Repository ), que es una sugerencia inútil porque @ Repository tiene todo lo que necesita tener, no tiene que configurar especialmente @ transaccional en DAOs, cuando se llama a los DAO desde los servicios que ya han sido inyectados por @Trasancational . Espero que esto pueda ser útil para las personas que usan Quartz, Spring e Hibernate juntos.
Mi problema similar se solucionó con los siguientes 2 enfoques.
Mediante el manejo manual de transacciones.
Session session = sessionFactory.getCurrentSession ();
Transacción tx = session.beginTransaction ();
UserInfo user = (UserInfo) session.get (UserInfo.class, 1);
tx.commit ();
Indique a Spring que abra y gestione transacciones para usted en sus filtros web.xml y asegúrese de usar @Repository @Transactional
<filtro> <nombre-filtro> hibernateFiltro </ filter-name> <clase-filtro> org.springframework.orm.hibernate5.support.OpenSessionInViewFilter </ filter-class> <init-param> <param-name> sessionFactory <param -value> session.factory </ init-param> </ filter> <filter-mapping> <filter-name> hibernateFilter </ filter-name> <url-pattern> / * </ url-pattern> </ filter- mapeo>
Perdón por el formateo incorrecto.
Tuve este error también porque en el archivo donde @Transactional
anotación @Transactional
, estaba importando la clase incorrecta
import javax.transaction.Transactional;
En lugar de javax, usa
import org.springframework.transaction.annotation.Transactional;
Verifica tu clase de Dao. Debe ser así:
Session session = getCurrentSession();
Query query = session.createQuery(GET_ALL);
Y anotaciones:
@Transactional
@Repository