Я создаю небольшое приложение, которое управляет двумя объектами, используя hibernate и spring MVC, одно из которых называется User
, а другое - Application
. Проблема в том, что при попытке ввести значения в базу данных (MySQL) я получаю следующую ошибку: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread.
Несмотря на эту ошибку, у меня есть необходимые примечания для выполнения транзакций, но она все равно не работает. Здесь я оставляю код: SpringConfig:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.test.app")
@PropertySource("classpath:/application.properties")
public class AppConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}
Конфигурация Hiberate:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@PropertySource("classpath:/application.properties")
@ComponentScan(basePackages = {
"com.test.app"
})
public class HibernateConfig {
@Autowired
private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.esliceu.examen.model");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
return properties;
}
@Bean
public HibernateTransactionManager getTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}
Контроллер приложений:
import com.test.app.model.Application;
import com.test.app.service.ApplicacionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
@Transactional
public class AplicacioController {
@Autowired
private AplicationService aplicationService;
@GetMapping("/applications")
private String testInsert(){
Application app = new Aplicacio();
app.setId(1);
app.setName("fooApp");
aplicacioService.insertOrUpdate(app);
return "applications";
}
}
ApplicationDao:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.annotation.PostConstruct;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
@Repository
public class AplicacioDao implements AppDao{
@Autowired
private SessionFactory sessionFactory;
@Override
public void insertOrUpdate(Aplication app) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(app);
}
}
Модель приложения:
import org.hibernate.envers.Audited;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "aplication")
@Audited
public class Aplicacio {
@Id
@Column(name = "idApp")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
@ManyToMany(mappedBy = "applications")
private List<User> ysers;
//...contructor, geters ands setters//
}
И это сервисный уровень:
package com.test.app.service;
import com.test.app.dao.ApplicationDao;
import com.test.app.model.Aplicacio;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ApplicationService implements AppService{
@Autowired
private AplicacioDao applicationDao;
public List<Application> findAll(){
return applicationDao.findAll();
}
@Override
public List<Application> findAllDatabase() {
return applicationDao.findAllDataBase();
}
@Override
public Application findById(int id) {
return applicationDao.findById(id);
}
@Override
public void insertOrUpdate(Application app) {
applicationDao.insertOrUpdate(app);
}
@Override
public void delete(Application app) {
applicationDao.delete(app);
}
}
Я все настраиваю с помощью аннотаций, как вы можете видеть, но я не вижу, где ошибка , Если бы кто-то мог сказать мне, где ошибка, я был бы очень благодарен