[英]Spring JPA Repository findAll returns no data in JUnit test
I have an issue with my integration tests of my jpa repository in a spring-boot web application. 我在spring-boot Web应用程序中对jpa存储库的集成测试有问题。 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. 但是,数据库的事务应包含数据,因为在日志显示测试事务已开始后,SQL脚本已正确执行。
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. 如果将代码用作Web服务,则可以按预期访问数据,因此这似乎与测试事务有关。
Can anyone point me to the right direction to solve this issue? 谁能指出我正确的方向来解决这个问题?
PS: @Data
is from https://projectlombok.org/ , which creates a complete bean. PS: @Data
来自https://projectlombok.org/ ,它创建了一个完整的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 SQL脚本
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: 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: 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: 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 依赖
I have found my error. 我发现了我的错误。
In the class HibernateConfiguration
i was overwriting the transactionManager. 在类HibernateConfiguration
我覆盖了transactionManager。 This was taken from a tutorial and seems to be unnecessary. 这是从教程中提取的,似乎是不必要的。
So the bean transactionManager
has been removed from the class. 因此,bean transactionManager
已从类中删除。
Also the annotations @EnableJpaRepositories("api")
, @EnableTransactionManagement
and the bean entityManagerFactory
could be removed. 另外,注释@EnableJpaRepositories("api")
@EnableTransactionManagement
和bean entityManagerFactory
可以被删除。
Configure H2 database 配置H2数据库
Open application.properties file, add configurations: 打开application.properties文件,添加配置:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.