No EntityManager with a real transaction available for the current thread - cannot reliably handle a persist call

No EntityManager with a real transaction available for the current thread - cannot reliably handle a persist call

when I do a test with JUnit, the persist method works, and I see that my object is inserted, but when I call the method through my controller, it does not work

here is my project:

applicationContext.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:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> <!-- <bean id="notification" class="com.app.sqli.notification.NotificationTask" /> --> <!-- <task:scheduled-tasks> --> <!-- <task:scheduled ref="notification" method="notifier" cron="*/2 * * * * *"/> --> <!-- </task:scheduled-tasks> --> <context:component-scan base-package="com.app.sqli" /> <mvc:annotation-driven /> <bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="com.app.sqli.entities" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> <property name="jpaProperties"> <props> <prop key="hibernate.hbm2ddl.auto">validate</prop> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> </props> </property> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/sqli" /> <property name="username" value="root" /> <property name="password" value="" /> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactoryBean" /> </bean> <tx:annotation-driven /> </beans> 

my model class:

 package com.app.sqli.models; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Collaborateur { @Id private int id; private String nom; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } } 

my class is DAO

 package com.app.sqli.dao; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.stereotype.Repository; import com.app.sqli.models.Collaborateur; @Repository public class CollaborateurDao implements IcollaborateurDao{ @PersistenceContext private EntityManager em; @Override public void addCollaborateur(Collaborateur c) { em.persist(c); } } 

My class of service

 package com.app.sqli.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.app.sqli.dao.IcollaborateurDao; import com.app.sqli.models.Collaborateur; @Service @Transactional public class CollaborateurService implements IcollaborateurService{ @Autowired private IcollaborateurDao cdao; @Override public void addCollaborateur(Collaborateur c) { cdao.addCollaborateur(c); } } 

And my controller

 package com.app.sqli.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import com.app.sqli.models.Collaborateur; import com.app.sqli.services.IcollaborateurService; @org.springframework.stereotype.Controller public class Controller { @Autowired private IcollaborateurService cserv; @RequestMapping(value = "/index") public String index(Model m) { System.out.println("insertion ..."); Collaborateur c = new Collaborateur(); c.setId(11); c.setNom("nom"); cserv.addCollaborateur(c); return "index"; } } 
+5
source share
3 answers

Thank you @mechkov for your time and help. My problem was solved by changing my configuration file, so I used the configuration class with annotations and its work is so beautiful that I still don’t know where the problem was

  @Configuration @ComponentScan(basePackages = "your package") @EnableTransactionManagement public class DatabaseConfig { protected static final String PROPERTY_NAME_DATABASE_DRIVER = "com.mysql.jdbc.Driver"; protected static final String PROPERTY_NAME_DATABASE_PASSWORD = "password"; protected static final String PROPERTY_NAME_DATABASE_URL = "jdbc:mysql://localhost:3306/databasename"; protected static final String PROPERTY_NAME_DATABASE_USERNAME = "login"; private static final String PROPERTY_PACKAGES_TO_SCAN = "where your models are"; @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){ LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); entityManagerFactoryBean.setDataSource(dataSource); entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter); entityManagerFactoryBean.setPackagesToScan(PROPERTY_PACKAGES_TO_SCAN); return entityManagerFactoryBean; } @Bean public BasicDataSource dataSource(){ BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName(PROPERTY_NAME_DATABASE_DRIVER); ds.setUrl(PROPERTY_NAME_DATABASE_URL); ds.setUsername(PROPERTY_NAME_DATABASE_USERNAME); ds.setPassword(PROPERTY_NAME_DATABASE_PASSWORD); ds.setInitialSize(5); return ds; } @Bean public JpaVendorAdapter jpaVendorAdapter(){ HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); adapter.setDatabase(Database.MYSQL); adapter.setShowSql(true); adapter.setGenerateDdl(true); //I'm using MySQL5InnoDBDialect to make my tables support foreign keys adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); return adapter; } @Bean public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } } 
+5
source

I don’t know if the one who reads this (today) has the same case as mine, but I had the same problem. Fortunately, I could fix this by simply adding the following to my spring -conf.xml:

 <beans xmlns="http://www.springframework.org/schema/beans" ... xmlns:tx="http://www.springframework.org/schema/tx" ... xsi:schemaLocation=" ... http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="tManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="emf" /> </bean> <!-- This does the trick! --> <tx:annotation-driven transaction-manager="tManager" /> 

Note. I use declarative transactions through annotations. So, if you do this, annotating your method with @Transactional can also solve your problem.

LINK:

+3
source

Just to confirm that adding the latest bean definition solves this problem!

My configuration class is as follows:

 @Configuration @EnableTransactionManagement @ComponentScan public class OFSConfig { @Bean public IDAO<FuelStation> getFSService() { return new FSService(); } @Bean public LocalEntityManagerFactoryBean emfBean() { LocalEntityManagerFactoryBean e = new LocalEntityManagerFactoryBean(); e.setPersistenceUnitName("org.superbapps.db_OWSDB_PU"); return e; } @Bean public PlatformTransactionManager transactionManager(EntityManagerFactory em) { return new JpaTransactionManager(em); } } 

The service itself is as follows:

 @Transactional @Repository public class FSService implements IDAO<FuelStation> { @PersistenceContext private EntityManager EM; public EntityManager getEM() { return EM; } public void setEM(EntityManager EM) { this.EM = EM; } @Override public List<FuelStation> getAll() { return EM.createNamedQuery("FuelStation.findAll") .getResultList(); } @Override public FuelStation getByID(String ID) { FuelStation fs = (FuelStation) EM.createNamedQuery("FuelStation.findById") .setParameter("id", ID) .getSingleResult(); return fs; } @Override public void update(FuelStation entity) { EM.merge(entity); } } 
+1
source

Source: https://habr.com/ru/post/1236232/


All Articles