Что не так в этой транзакции Sping MVC и Hibernate? - PullRequest
0 голосов
/ 16 февраля 2020

Я создаю небольшое приложение, которое управляет двумя объектами, используя 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);
    }
}

Я все настраиваю с помощью аннотаций, как вы можете видеть, но я не вижу, где ошибка , Если бы кто-то мог сказать мне, где ошибка, я был бы очень благодарен

1 Ответ

2 голосов
/ 16 февраля 2020

Попробуйте это для сервисного уровня, удалив @Transactional из DAO и контроллера:

@Service
@Transactional
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);
    }
}

Или проблема с классом HibernateConfig, пожалуйста, проверьте это.

...