J'ai créé une application avec spring + hibernate, mais j'obtiens toujours cette erreur. C'est ma première application avec hibernate, j'ai lu quelques guides mais je n'arrive pas à résoudre ce problème. Où vais-je mal?
Ceci est le code de mon application
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
étudiantDAO.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)
);
sessionFactory.openSession()
la transaction sera désactivée. Parce qu'ils ne sont pas la même session. > Ajouter l'annotation @Transactional of spring dans la classe service @Patrikoko c'est correct! voir cette question: stackoverflow.com/questions/15620355/… exemple:@Transactional(readOnly = true, propagation = Propagation.REQUIRED, rollbackFor = {java.lang.Exception.class})
Réponses:
Vous devez activer la prise en charge des transactions (
<tx:annotation-driven>
ou@EnableTransactionManagement
) et déclarer letransactionManager
et il devrait fonctionner via leSessionFactory
.Vous devez ajouter
@Transactional
à votre@Repository
With
@Transactional
in your@Repository
Spring est capable d'appliquer le support transactionnel dans votre référentiel.Votre
Student
classe n'a pas d'annotations @ javax.persistence. * Comment@Entity
, je suppose que la configuration de mappage pour cette classe a été définie via XML.la source
J'ai eu le même problème, mais dans une classe qui ne faisait pas partie de la couche de service. Dans mon cas, le gestionnaire de transactions a simplement été obtenu à partir du contexte par la
getBean()
méthode, et la classe appartenait à la couche de vue - mon projet utilise laOpenSessionInView
technique.La
sessionFactory.getCurrentSession()
méthode a causé la même exception que celle de l'auteur. La solution pour moi était plutôt simple.Si la
getCurrentSession()
méthode échoue, leopenSession()
devrait faire l'affaire.la source
sessionFactory.getCurrentSession();
réussit, la session ne doit pas être fermée mais sisessionFactory.openSession();
elle réussit, elle doit être ferméeFunction<Session,T>
signifiant "si j'avais une session, je l'utiliserais pour faire X". Ensuite, la méthode gère l'approvisionnement et (si nécessaire) la suppression du provisionnement de la session, et renvoie simplement le T.Ainsi, les consommateurs externes du service ne mettent jamais la main sur une sessionAjouter l'annotation @Transactional of spring dans le service de classe
la source
Dans votre xyz.DAOImpl.java
Suivez les étapes suivantes:
la source
J'ai ajouté ces configurations dans web.xml et cela fonctionne bien pour moi!
De plus, la réponse la plus classée me donne des indices pour empêcher l'application de paniquer lors de la première exécution.
la source
Vous devez autoriser la transaction à votre méthode DAO. Ajouter,
sur vos méthodes dao. Et
@Transactional
devrait être du paquet:la source
J'ai eu cette erreur aussi parce que dans le fichier où j'ai utilisé l'
@Transactional
annotation, j'importais la mauvaise classeAu lieu de javax, utilisez
la source
Ma solution consistait (en utilisant Spring) à mettre la méthode qui échoue dans une autre méthode qui crée et valide la transaction.
Pour ce faire, j'ai d'abord injecté ce qui suit:
Et finalement fait ceci:
la source
@Transactional =javax.transaction.Transactional
. Mettez-le juste à côté@Repository
.la source
Ma configuration était comme ça. J'avais un QuartzJob , un Service Bean et Dao. comme d'habitude, il a été configuré avec LocalSessionFactoryBean (pour la mise en veille prolongée) et SchedulerFactoryBean pour le framework Quartz. lors de l'écriture du travail Quartz, je l'ai par erreur annoté avec @ Service , je n'aurais pas dû le faire car j'utilisais une autre stratégie pour câbler le QuartzBean en utilisant AutowiringSpringBeanJobFactory étendant SpringBeanJobFactory .
Donc, ce qui se passait réellement, c'est qu'en raison de Quartz Autowire, TX était injecté dans le Job Bean et en même temps, le contexte Tx était défini en vertu de @ Service annotation et donc le TX tombait hors de synchronisation !!
J'espère que cela aidera ceux pour qui les solutions ci-dessus n'ont vraiment pas résolu le problème. J'utilisais Spring 4.2.5 et Hibernate 4.0.1,
Je vois que dans ce fil, il y a une suggestion inutile d'ajouter une annotation @ Transactional au DAO (@ Repository ), c'est une suggestion inutile car @ Repository a tout ce dont il a besoin pour ne pas avoir à définir spécialement ce @ transactionnel sur DAO, comme les DAO sont appelés à partir des services qui ont déjà été injectés par @Trasancational . J'espère que cela pourrait être utile aux personnes qui utilisent ensemble Quartz, Spring et Hibernate.
la source
Ajouter
transaction-manager
à votre<annotation-driven/>
au printemps servlet.xml:la source
Vérifiez votre classe de dao. Ça doit être comme ça:
Et annotations:
la source
J'ai rencontré le même problème et j'ai finalement découvert que le
<tx:annotaion-driven />
n'était pas défini dans la classe annotée[dispatcher]-servlet.xml
where component-scan element enabled@service
.Simplement mis ensemble
<tx:annotaion-driven />
avec l'élément d'analyse de composant, le problème a disparu.la source
Mon problème similaire a été résolu avec les 2 approches ci-dessous.
1) Grâce à la gestion manuelle des transactions:
2) Dites à Spring d'ouvrir et de gérer les transactions pour vous dans vos
web.xml
filtres et assurez-vous d'utiliser@Repository
@Transactional
:la source
Merci pour le commentaire de mannedear. J'utilise springmvc et dans mon cas je dois utiliser comme
et j'ajoute également spring-context à pom.xml et cela fonctionne
la source
J'ai eu le même problème. Je l'ai résolu en procédant comme suit:
Ajoutez la ligne this au
dispatcher-servlet
fichier:Vérifiez la
<beans>
section ci - dessus dans le même fichier. Ces deux lignes doivent être présentes:Assurez-vous également que vous avez ajouté
@Repository
et@Transactional
où vous utilisezsessionFactory
.la source
Dans cette classe ci
@Repository
- dessus vient de placer une autre annotation,@Transactional
cela fonctionnera. Si cela fonctionne, répondez (Y
/N
):la source