2

This error occurs at this.itemRepository.deleteAll() when sampleTest() method is run.

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

Adding @Transactional annotation to restoreInitialData() does not solve the problem - https://stackoverflow.com/a/32552558/3536552

Do you know how to fix it?

Kamil Pajak
  • 340
  • 2
  • 13
  • did you try making the whole class `@Traansactional`? – pvpkiran Nov 02 '17 at 10:26
  • @pvpkiran Yes I tried but it didn't help – Kamil Pajak Nov 02 '17 at 10:28
  • which version of spring boot are you using. because in the latest version `AutoConfigureTestDatabase` is deprecated – pvpkiran Nov 02 '17 at 10:34
  • @pvpkiran I use `2.0.0.M5` – Kamil Pajak Nov 02 '17 at 10:37
  • I think the problem is `restoreInitialData` is called from setup which is a `@BeforeAll` method. May be spring hasnt stepped in at that point to have a transaction created. Just change this to `@BeforeEach` and check and also with `@Transactional`. Just a guess – pvpkiran Nov 02 '17 at 10:41
  • @pvpkiran Indeed when I changed `@BeforeAll` to `@BeforeEach` test runs without an error, however I would like `restoreInitialData()` method to be invoked just once. – Kamil Pajak Nov 02 '17 at 10:49

2 Answers2

1

I think the problem is restoreInitialData is called from setup which is a @BeforeAll method. Spring hasn't stepped in at that point to have a transaction created. Just change this to @BeforeEach and check and also with @Transactional. If you want something to be executed only once. Try this approach

private static boolean setUpIsDone = false;
.....
public void setUp() {
    if (setUpIsDone) {
        return;
    }
    // do the setup
    setUpIsDone = true;
}
pvpkiran
  • 25,582
  • 8
  • 87
  • 134
0

By default Spring provides implementations of Interface and Class but with the test environment spring expect you to provide its implementation. So use following code to provide EntityManager implementation.

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;
    }
}
Vicky Thakor
  • 3,847
  • 7
  • 42
  • 67