Spring JPA Repository findAll returns no data in JUnit test

五迷三道 提交于 2019-12-11 06:07:11

问题


I have an issue with my integration tests of my jpa repository in a spring-boot web application. A test of a service method fails, because the accessed repository does not return any results. But the transaction for the database should contain data, because the SQL script gets executed correctly, after the log shows that the transaction for the test has begun.

If the code is used as Web-service, the data can be accessed as expected, so it seems to be a problem with the transaction of the test.

Can anyone point me to the right direction to solve this issue?

PS: @Data is from https://projectlombok.org/, which creates a complete bean.

Here is my corresponding code:

Entity

@Entity
@Data
public class ConcreteEvent {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private long id;
   private String caption;
   private String description;
   @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
   private DateTime startDate;
   @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
   private DateTime endDate;
}

Repository

public interface ConcreteEventRepository 
    extends PagingAndSortingRepository<ConcreteEvent, Long> {
}

Service

@Service
public class CalenderEventServiceImpl implements CalendarEventService {

    @Autowired
    private ConcreteEventRepository concreteEventRepository;

    @Override
    public List<ConcreteEvent> getCalendarEventsForDay(DateTime day) {
        List<ConcreteEvent> list = new ArrayList<>();
        Iterable<ConcreteEvent> findAll = concreteEventRepository.findAll();
        findAll.forEach(list::add);
        return list;
    }
}

Test

@ActiveProfiles("test")
@SpringApplicationConfiguration(Application.class)
@WebAppConfiguration
@DirtiesContext
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class })
public class CalendarEventServiceTest 
    extends AbstractTransactionalJUnit4SpringContextTests {

    @Autowired
    private CalendarEventService calendarEventService;

    @Before
    public void initialize()
    {
        executeSqlScript("classpath:concreteEvents.sql", false);
    }

    @Test
    public void testGetCalendarEventsForDay_UseConcreteEvents() {
        List<ConcreteEvent> calendarEventsForDateTime = calendarEventService.getCalendarEventsForDay(new DateTime(2016, 06, 20, 18, 00));

        assertNotNull("No list of events retrieved", calendarEventsForDateTime);
        assertEquals("Not the correct number of events retrieved", 2, calendarEventsForDateTime.size());
    }
}

SQL-Script

INSERT INTO CONCRETEEVENT (ID, CAPTION, DESCRIPTION, STARTDATE, ENDDATE) values (1, 'TestEvent1', 'Test Description 1', PARSEDATETIME('2016-06-24 18:00', 'yyyy-MM-dd hh:mm'), PARSEDATETIME('2016-06-24 20:00', 'yyyy-MM-dd hh:mm'));

INSERT INTO CONCRETEEVENT (ID, CAPTION, DESCRIPTION, STARTDATE, ENDDATE) values (2, 'TestEvent2', 'Test Description 2', PARSEDATETIME('2016-06-24 18:15', 'yyyy-MM-dd hh:mm'), PARSEDATETIME('2016-06-24 20:15', 'yyyy-MM-dd hh:mm'));

Log

o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@6b09bb57 testClass = CalendarEventServiceTest, testInstance = service.CalendarEventServiceTest@556aed22, testMethod = testGetCalendarEventsForDay_UseConcreteEvents@CalendarEventServiceTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@6536e911 testClass = CalendarEventServiceTest, locations = '{}', classes = '{class api.Application}', contextInitializerClasses = '[]', activeProfiles = '{test}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.hibernate5.HibernateTransactionManager@3b66ac74]; rollback [true]
o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [api/calendar/service/concreteEvents.sql]
o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [api/calendar/service/concreteEvents.sql] in 7 ms.
o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory
o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test context [DefaultTestContext@6b09bb57 testClass = CalendarEventServiceTest, testInstance = api.calendar.service.CalendarEventServiceTest@556aed22, testMethod = testGetCalendarEventsForDay_UseConcreteEvents@CalendarEventServiceTest, testException = java.lang.AssertionError: Not the correct number of events retrieved expected:<2> but was:<0>, mergedContextConfiguration = [WebMergedContextConfiguration@6536e911 testClass = CalendarEventServiceTest, locations = '{}', classes = '{class api.Application}', contextInitializerClasses = '[]', activeProfiles = '{test}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]].
o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@56620197: startup date [Fri Jun 24 22:50:25 CEST 2016]; root of context hierarchy

Configuration

HibernateTestConfiguration:

@Configuration
@Profile("test")
public class HibernateTestConfiguration extends HibernateConfiguration {

    @Bean
    @Override
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setPassword(environment.getRequiredProperty("jdbc.test.password"));
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:dataSource;DB_CLOSE_DELAY=-1");
        dataSource.setUsername("sa");
        dataSource.setPassword("");
        return dataSource;
    }

    @Override
    protected Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
        properties.put("hibernate.show_sql", "true");
        properties.put("hibernate.format_sql", "true");
        properties.put("hibernate.hbm2ddl.auto", "create");
        return properties;
    }
}

HibernateConfiguration:

@Configuration
@EnableJpaRepositories("api")
@EnableTransactionManagement
@PropertySource(value = { "classpath:application.properties" })
@Profile("default")
public class HibernateConfiguration {

    private static final String[] PACKAGES_TO_SCAN = new String[] { "api" };
    @Autowired
    protected Environment environment;

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());        
        sessionFactory.setPackagesToScan(PACKAGES_TO_SCAN);
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }  

    @Bean
    public EntityManagerFactory entityManagerFactory() {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan(PACKAGES_TO_SCAN);
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();

        return factory.getObject();
    }

    @Bean
    public DataSource dataSource() {
        // stripped for brevity
    }

    protected Properties hibernateProperties() {
        // stripped for brevity
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory s) {
       HibernateTransactionManager txManager = new HibernateTransactionManager();
       txManager.setSessionFactory(s);
       return txManager;
    }
}

AppConfiguration:

@Configuration
@EnableAutoConfiguration
@ComponentScan("api")
@EnableWebMvc
public class AppConfiguration {

}

Application:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Dependencies

  • spring-boot-starter-web: 1.3.5
  • spring-boot-starter-data-jpa: 1.3.5
  • spring-boot-starter-test: 1.3.5
  • spring-test: 4.2.6
  • spring-orm: 4.2.6
  • h2: 1.4.191

回答1:


I have found my error.

In the class HibernateConfiguration i was overwriting the transactionManager. This was taken from a tutorial and seems to be unnecessary.

So the bean transactionManager has been removed from the class.

Also the annotations @EnableJpaRepositories("api"), @EnableTransactionManagement and the bean entityManagerFactory could be removed.




回答2:


Configure H2 database
Open application.properties file, add configurations:

spring.h2.console.enabled=true  
spring.h2.console.path=/h2_console  
spring.datasource.url=jdbc:h2:file:~/h2/testdb  
spring.datasource.username=sa  
spring.datasource.password=  
spring.datasource.driverClassName=org.h2.Driver  
spring.jpa.hibernate.ddl-auto = update  
spring.jpa.show-sql=true  


来源:https://stackoverflow.com/questions/38022284/spring-jpa-repository-findall-returns-no-data-in-junit-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!