@Transactional not working in Spring Boot.
Application.java :
@EnableTransactionManagement(proxyTargetClass=true) @SpringBootApplication(exclude = {ErrorMvcAutoConfiguration.class}) public class Application { @Autowired private EntityManagerFactory entityManagerFactory; public static void main(String[] args) { System.out.println("--------------------------- Start Application ---------------------------"); ApplicationContext ctx = SpringApplication.run(Application.class, args); } @Bean public SessionFactory getSessionFactory() { if (entityManagerFactory.unwrap(SessionFactory.class) == null) { throw new NullPointerException("factory is not a hibernate factory"); } return entityManagerFactory.unwrap(SessionFactory.class); } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); em.setPackagesToScan(new String[] { "com.buhryn.interviewer.models" }); JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); em.setJpaProperties(additionalProperties()); return em; } @Bean public DataSource dataSource(){ DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.postgresql.Driver"); dataSource.setUrl("jdbc:postgresql://localhost:5432/interviewer"); dataSource.setUsername("postgres"); dataSource.setPassword("postgres"); return dataSource; } @Bean @Autowired public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) { HibernateTransactionManager txManager = new HibernateTransactionManager(); txManager.setSessionFactory(sessionFactory); return txManager; } @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){ return new PersistenceExceptionTranslationPostProcessor(); } Properties additionalProperties() { Properties properties = new Properties(); properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); properties.setProperty("hibernate.show_sql", "false"); properties.setProperty("hibernate.format_sql", "false"); properties.setProperty("hibernate.hbm2ddl.auto", "create"); properties.setProperty("hibernate.current_session_context_class", "org.hibernate.context.internal.ThreadLocalSessionContext"); return properties; } } CandidateDao.java
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @Repository public class CandidateDao implements ICandidateDao{ @Autowired SessionFactory sessionFactory; protected Session getCurrentSession(){ return sessionFactory.getCurrentSession(); } @Override @Transactional public CandidateModel create(CandidateDto candidate) { CandidateModel candidateModel = new CandidateModel(candidate.getFirstName(), candidate.getLastName(), candidate.getEmail(), candidate.getPhone()); getCurrentSession().save(candidateModel); return candidateModel; } @Override public CandidateModel show(Long id) { return new CandidateModel( "new", "new", "new", "new"); } @Override public CandidateModel update(Long id, CandidateDto candidate) { return new CandidateModel( "updated", candidate.getLastName(), candidate.getEmail(), candidate.getPhone()); } @Override public void delete(Long id) { } } Service Class
@Service public class CandidateService implements ICandidateService{ @Autowired ICandidateDao candidateDao; @Override public CandidateModel create(CandidateDto candidate) { return candidateDao.create(candidate); } @Override public CandidateModel show(Long id) { return candidateDao.show(id); } @Override public CandidateModel update(Long id, CandidateDto candidate) { return candidateDao.update(id, candidate); } @Override public void delete(Long id) { candidateDao.delete(id); } } Controller.class
@RestController @RequestMapping(value = "/api/candidates") public class CandidateController { @Autowired ICandidateService candidateService; @RequestMapping(value="/{id}", method = RequestMethod.GET) public CandidateModel show(@PathVariable("id") Long id) { return candidateService.show(id); } @RequestMapping(method = RequestMethod.POST) public CandidateModel create(@Valid @RequestBody CandidateDto candidate, BindingResult result) { RequestValidator.validate(result); return candidateService.create(candidate); } @RequestMapping(value="/{id}", method = RequestMethod.PUT) public CandidateModel update(@PathVariable("id") Long id, @Valid @RequestBody CandidateDto candidate, BindingResult result) { RequestValidator.validate(result); return candidateService.update(id, candidate); } @RequestMapping(value="/{id}", method = RequestMethod.DELETE) public void delete(@PathVariable("id") Long id) { candidateService.delete(id); } } When I call create method in DAO system throw exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: save is not valid without active transaction; nested exception is org.hibernate.HibernateException: save is not valid without active transaction org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868) javax.servlet.http.HttpServlet.service(HttpServlet.java:644) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) javax.servlet.http.HttpServlet.service(HttpServlet.java:725) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:291) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:102) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:90) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) My Gradle file :
buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE") } } apply plugin: 'java' apply plugin: 'idea' apply plugin: 'spring-boot' jar { baseName = 'interviewer' version = '0.1.0' } repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-starter-actuator") compile("org.codehaus.jackson:jackson-mapper-asl:1.9.13") compile("com.google.code.gson:gson:2.3.1") compile("org.springframework.data:spring-data-jpa:1.8.0.RELEASE") compile("org.hibernate:hibernate-entitymanager:4.3.10.Final") compile("postgresql:postgresql:9.1-901-1.jdbc4") compile("org.aspectj:aspectjweaver:1.8.6") testCompile("org.springframework.boot:spring-boot-starter-test") } task wrapper(type: Wrapper) { gradleVersion = '2.3' } And link to git repository : https://github.com/Yurii-Buhryn/interviewer