Search code examples
javaspringjpaspring-java-config

Spring Java Config. Transaction problems


I have a spring application with java config:

@Controller
@RequestMapping("/")
public class MainController {

    @Inject
    @Named("dbDaoService")
    IDaoService dbDaoService;

    @RequestMapping(value="/saveNoteAsync", method = RequestMethod.POST)
    public @ResponseBody String saveNoteAsync(@RequestBody CreateRequest createRequest, HttpServletRequest request) {
        Notes newNote = new Notes(
            createRequest.getTitle(),
            createRequest.getNote(),
            tagService.getTagMask(createRequest.getTags())
        );

        Long newId = dbDaoService.createNotes(newNote);
        return ""+newId;
    }

}

DBService:

@Service("dbDaoService")
public class DBDaoService implements IDaoService {

@PersistenceContext(unitName = "MyEntityManager")
private EntityManager entityManager;

private List<Tags> tags = null;

@Override
@Transactional
public Long createNotes(Notes data) {
        entityManager.persist(data);

        return data.getId();
    }
}

Configuration class

@Configuration
@EnableWebMvc
@ComponentScan("ru.mypackage")
public class WebConfig extends WebMvcConfigurerAdapter {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/WEB-INF/views/**").addResourceLocations("/views/");
}

@Bean
public InternalResourceViewResolver getViewResolver() {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    resolver.setViewClass(JstlView.class);

    return resolver;
}

@Bean
public BasicDataSource getBasicDataSource(){
    BasicDataSource bds = new BasicDataSource();
    bds.setDriverClassName("com.mysql.jdbc.Driver");
    bds.setUrl("jdbc:mysql://localhost:3306/test");
    bds.setUsername("root");
    bds.setPassword("root");

    return bds;
}

@Bean
public HibernateJpaVendorAdapter getHibernateJpaVendorAdapter(){
    HibernateJpaVendorAdapter hjva = new HibernateJpaVendorAdapter();
    hjva.setShowSql(true);
    hjva.setGenerateDdl(true);
    hjva.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");

    return hjva;
}

@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setPersistenceUnitName("MyEntityManager");
    em.setDataSource(getBasicDataSource());
    em.setJpaVendorAdapter(getHibernateJpaVendorAdapter());
    em.setPackagesToScan("ru.eastwind.persistance");

    return em;
}

@Bean
public HibernateJpaDialect getHibernateJpaDialect(){
    return new HibernateJpaDialect();
}

@Bean
public JpaTransactionManager getJpaTransactionManager(){
    JpaTransactionManager jtm = new JpaTransactionManager();
    jtm.setEntityManagerFactory(getEntityManagerFactory().getObject());
    jtm.setJpaDialect(getHibernateJpaDialect());

    return jtm;
}
}

In line entityManager.persist(data); I get the error:

javax.persistence.TransactionRequiredException: No transactional EntityManager available

But all select queries are woking correct! Please, help.


Solution

  • Use @EnableTransactionManagement on @Configuration class

    @Configuration
    @EnableWebMvc
    @ComponentScan("ru.mypackage")
    @EnableTransactionManagement
    public class WebConfig extends WebMvcConfigurerAdapter {
        // ... Your code 
    }
    

    See Also : http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html