没有可用于当前线程的实际事务的EntityManager

时间:2017-11-02 10:05:00

标签: java spring hibernate spring-boot

运行this.itemRepository.deleteAll()方法时,sampleTest()会发生此错误。

@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Rollback(false)
public class ScheduleTests {

    private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleTests.class);

    @Autowired
    private ScheduleRepository scheduleRepository;

    @Autowired
    private ItemRepository itemRepository;

    @Autowired
    private ItemQualifierRepository itemQualifierRepository;

    @Autowired
    private MappingRepository mappingRepository;

    @BeforeAll
    public void setUp() {
        restoreInitialData();
        LOGGER.info("Initial data restored");
    }

    @Test
    public void sampleTest() {
        File feed = new File("target/test-classes/TestFeedOK.json");
        Feed.ingest(feed);
        LOGGER.info("Feed {} ingested", feed.getName());
    }

    private void restoreInitialData() {
        this.itemRepository.deleteAll();
        this.mappingRepository.deleteByTableName("event");
    }
}

@Transactional注释添加到restoreInitialData()无法解决问题 - https://stackoverflow.com/a/32552558/3536552

你知道怎么解决吗?

2 个答案:

答案 0 :(得分:0)

我认为问题是from collections import defaultdict latin_dic = {'apple': ['malum', 'pomum', 'popula'], 'fruit': ['baca', 'bacca', 'popum'], 'punishment': ['malum', 'multa']} english_dic = defaultdict(list) for k in latin_dic: for v in latin_dic[k]: english_dic[v].append(k) for k in sorted(english_dic): print(k, '-', english_dic[k]) 是从restoreInitialData调用的,这是一个@BeforeAll方法。   Spring此时并未介入创建事务。只需将其更改为@BeforeEach并检查并使用@Transactional。    如果你想要只执行一次。试试这种方法

setup

答案 1 :(得分:0)

默认情况下,Spring提供InterfaceClass的实现,但是测试环境spring希望您提供它的实现。因此,请使用以下代码来提供EntityManager实现。

<强> PersistenceJPAConfig.java

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {

    @Autowired
    private Environment environment; 

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[] { "com.example.db.model" });

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());
        return em;
    }

    @Bean
    public DataSource dataSource() {
        String driverClassName = environment.getProperty("spring.datasource.driverClassName");
        String url = environment.getProperty("spring.datasource.url");
        String username = environment.getProperty("spring.datasource.username");
        String password = environment.getProperty("spring.datasource.password");

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);

        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.id.new_generator_mappings","false");
        return properties;
    }
}