java - Spring Boot + Hibernate JPA 在 @Service 层中没有具有实际事务的 EntityManager

标签 java spring hibernate spring-boot

我正在自己配置 Spring Boot 应用程序以与两个数据库一起运行(两个 transactionManager 相同)。 MariaDB 和 MongoDB。在 @Repository 中,我将 @Autowired 与 @PersistenceContext 一起使用,注释 @Transactional 与 TransactionManager 一起正常工作。 但对我来说,最有用的是在 @Services 层上使用 @Transacional。但是当我这样做时,我遇到了问题

No EntityManager with actual transaction available for current thread

这是 @Repository 和 JpaRepository 的配置(我将在两种方式的抽象上进行编码以扩展我的知识:))

    package com.kamil.serwis.config;


@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryMySQL",
        basePackages = "com.kamil.serwis.repository",
        transactionManagerRef = "MySQLTransactionManager")
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.kamil.serwis.repository.dao.SQL"})
public class HibernateConfiguration {

    private final String URLDatabase = "jdbc:mariadb://localhost:3306/SerwisDB";
    private final String User = "test";
    private final String Password = "password";
    private final String SQLDatabase = "org.mariadb.jdbc.Driver";


    @Bean(name ="entityManagerFactoryMySQL")
    @Primary
    LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf =
                new LocalContainerEntityManagerFactoryBean();
        emf.setPackagesToScan("com.kamil.serwis.model.SQL");
        emf.setDataSource(createDataSource());
        emf.setJpaVendorAdapter(createJpaVendorAdapter());
        emf.setJpaProperties(createHibernateProperties());
        emf.setPersistenceUnitName("MySQLPersistence");
//        emf.afterPropertiesSet();
        System.out.println("Data source do bazy" + emf.getDataSource().toString() + " " +emf.getPersistenceUnitName());
        return emf;
    }
    @Primary
    private DataSource createDataSource() {
        DataSource dataSource= DataSourceBuilder.create()
                .url(this.URLDatabase)
                .username(User)
                .password(Password)
                .driverClassName(SQLDatabase)
                .build();
        return dataSource;
    }
    @Primary
    private JpaVendorAdapter createJpaVendorAdapter() {
        return new HibernateJpaVendorAdapter();
    }
    @Primary
    private Properties createHibernateProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create");
        properties.setProperty(
                "hibernate.dialect", "org.hibernate.dialect.MySQL55Dialect");
        properties.setProperty("hibernate.show_sql","true");
        /*properties.setProperty("com.mysql.cj.jdbc.Driver","");*/
        return properties;
    }

    @Bean(name = "MySQLTransactionManager")
    @Primary
    PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactoryMySQL") EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }

}

在@Service中,我遇到了“没有带有实际事务的EntityManager...”的问题,我想我必须说SpringBoot关于“在方法上使用此事务”,但我的SpringBoot在@Service层中没有看到TransactionManager,是吗?因为在 @Repository 中,当我添加 @Transactional 时一切正常。

如何配置?你能帮我吗?

还有简单的@repository,它与@transactional配合良好,但我更喜欢服务层中的@transactional(但现在它对我不起作用)。

@Repository 示例:

@Repository
public class UserRepository {

    @PersistenceContext(name = "MySQLPersistence")
    @Autowired
    private EntityManager entityManager;


    public User addUserToDB(User newUser){
        entityManager.persist(newUser);
        return newUser;
    }

    public User findUserByName(String userName){
        User user = (User)entityManager.createQuery( "select u from User u").getResultStream().findFirst().get();
        return user;
    }

    public boolean deleteUser(User userToDelete){
        entityManager.remove(userToDelete);
        return entityManager.find(User.class,userToDelete.getId()).equals(userToDelete);
    }
}

编辑 我为 jpa 和 Spring 上下文尝试了 @transactional

    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import javax.annotation.PostConstruct;
    import javax.transaction.TransactionManager;

    @Service
    public class UserService {

        private UserRepository userRepository;

        @Autowired
        public UserService(UserRepository userRepository){
            this.userRepository = userRepository;
        }

        @Transactional(transactionManager = "entityManagerFactoryMySQL")
        //@javax.transaction.Transactional
        @PostConstruct
        public void createUser(){
            User newUser = new User("test");
            User usersaved = userRepository.addUserToDB(newUser);
        }
    }

最佳答案

将服务层更新为:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;

@Service
public class UserService {

    private UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository){
        this.userRepository = userRepository;
    }

    @Transactional("MySQLTransactionManager")
    @PostConstruct
    public void createUser(){
        User newUser = new User("test");
        User usersaved = userRepository.addUserToDB(newUser);
    }
}

关于java - Spring Boot + Hibernate JPA 在 @Service 层中没有具有实际事务的 EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60460295/

相关文章:

java - 使用 jsp 的 ajax 返回填充 div

spring - 为什么 Jersey 显示在我的 Spring boot MVC 上

java - 使用 Hibernate 和 spring 检查数据库中是否存在一行的最快方法是什么?

java - 应该填充的集合为空

java - 批量插入中的 Postgres 错误 : relation "hibernate_sequence" does not exist position 17

java - 使用Java Reflection初始化成员变量

java - 使用 Java Streams 对 concat 字符串执行算术运算

java - 使用 Java 将媒体放入 Access 数据库

spring - 应用程序上下文异常 : Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean

java - 如何将 Spring 集成到 Cucumber 中