Обычно, когда я запускаю приложение Spring Boot с Spring Data JPA, в тестах происходит откат транзакций автоматически, и тестовая база данных не изменяется. Это поведение не работает, однако, с MySQL8.
У меня есть тривиальный POJO под названием Category
.
@Entity
@Table(name = "categories")
public class Category {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "category_id")
private Integer id;
@Column(name = "category_name")
private String name;
// ... constructors, getters and setters, etc, omitted ...
}
Вот мой еще более простой интерфейс репозитория:
public interface CategoryRepository extends JpaRepository<Category,Integer> {
}
У меня есть существующая база данных, и вот мои application.properties
настройки для доступа к ней:
spring.datasource.url=jdbc:mysql://localhost:3306/dashboard
spring.datasource.username=admin
spring.datasource.password=not_password
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
В настоящее время в таблице 10 категорий. Мой тест проверяет их, и другой тест вставляет новый.
@DataJpaTest
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
class CategoryRepositoryTest {
@Autowired
private CategoryRepository dao;
@Test
void findAll() {
List<Category> categories = dao.findAll();
assertEquals(10, categories.size());
}
@Test
void insertCategory() {
Category cat = new Category("Misc");
assertNull(cat.getId());
cat = dao.save(cat);
assertNotNull(cat.getId());
System.out.println(cat);
}
}
Обратите внимание, что @DataJpaTest
уже включает @Transactional
. Результат второго теста:
2019-10-03 14:26:48.844 INFO 91485 --- [ Test worker] o.s.t.c.transaction.TransactionContext : Began transaction (1) for test context [DefaultTestContext@67e4b73d testClass = CategoryRepositoryTest, testInstance = com.kousenit.simpledemo.dao.CategoryRepositoryTest@3913544f, testMethod = insertCategory@CategoryRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@7314dd45 testClass = CategoryRepositoryTest, locations = '{}', classes = '{class com.kousenit.simpledemo.MyApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@3c6df497, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@8b9f8fd, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@15acb0c6, [ImportsContextCustomizer@76c5962 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@21f27cf2, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@67568498, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@4a3861f3]; rollback [true]
Hibernate:
insert
into
categories
(category_name)
values
(?)
Category{id=11, name='Misc'}
2019-10-03 14:26:48.880 INFO 91485 --- [ Test worker] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test: [DefaultTestContext@67e4b73d testClass = CategoryRepositoryTest, testInstance = com.kousenit.simpledemo.dao.CategoryRepositoryTest@3913544f, testMethod = insertCategory@CategoryRepositoryTest, ...
Проблема в том, что после завершения теста у меня все еще есть новая категория в базе данных. С H2 транзакции откатились, а его там не было, но с MySQL 8, хотя откат происходит, вставленный элемент остается.
Что здесь отличается? Как это исправить, чтобы вставка сбрасывалась в конце теста?