当前位置: 首页 > 知识库问答 >
问题:

SpringBoot+Hibernate JPA在@service层没有带有actuall事务的EntityManager

狄旭
2023-03-14

我正在自己配置Spring Boot应用程序,以运行两个数据库(两个transactionManager相同)。MariaDB和MongoDb。在@Repository中,我已经用@PersistenceContext使用了@Autowired,注释@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);
    }

}

@存储库示例:

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

共有1个答案

申屠新觉
2023-03-14

将服务层更新为:

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);
    }
}
 类似资料:
  • 根据这里的baeldung 如果我们使用的是Spring Boot项目,并且在类路径上有spring-data-*或spring-tx>依赖项,那么事务管理将通过>default启用。“ serviceConfig.java 哪里出了问题?,我在SpringBoot配置中遗漏了什么? 提前感谢你的帮助

  • 我正在Spring3和Hibernate3中进行产品构建,我已经更新了这个Hibernate5和Spring5。现在我可以部署应用程序了,但是当我尝试与数据库连接时,会得到“javax.persistence.TransactionRequiredException:no transaction is in progress”

  • 我需要使用表锁定(写入)并同时更新几个表,因此我需要同时进行事务,因为锁定不是事务安全的。 从mysql文档中,我阅读了以下 https://dev.mysql.com/doc/refman/5.6/en/lock-tables-and-transactions.html 对事务表(如InnoDB表)使用LOCK TABLES和UNLOCK TALES的正确方法是以SET autocommit=0

  • 问题内容: 项目使用Hibernate(JPA),Spring和Maven。我的实体和DAO在单独的JAR中。 pom.xml: 道: } 我有一个使用Spring的模块。 pom.xml: AppContext.xml: 服务: 当我尝试从EntityManager中获取会话时,遇到以下异常: 问题答案: 您必须在方法周围加上@Transactional批注: 并在您的Spring的xml配置文

  • 答案可能涵盖所有框架,但我对SpringMVC案例特别感兴趣。我正在重构一个访问内部数据库和远程服务的服务层。这些方法应该是事务性的,它们需要来自远程服务的数据。下面是类似的伪代码: 这样更容易实现。但是有许多缺点,例如当远程服务调用失败时不必要地创建和回滚事务,由于远程服务调用而导致的事务更长,并且可能更复杂。我正在考虑将服务调用移动到单独的非事务性方法,并调用事务性方法,如下面的代码段所示 假