Я пытаюсь повысить скорость наших тестов базы данных flyway. Первоначальный метод должен был запускать flyway.clear()
и flyway.migrate()
между каждым тестовым прогоном. Проблема, однако, в том, что теперь у нас есть несколько потенциально долго выполняемых сценариев миграции с миграционного пути, и мы не хотим повторять их между каждым тестом.
Я пытался использовать пружинную аннотацию @Transactional для отката базы данных после каждого теста, тогда нам нужно запустить пролет только один раз.
Проблема в том, что как только я добавляю транзакции вокруг теста, JPA перестает извлекать внешние ключи. Я предполагаю, что это потому, что вложенные транзакции ведут себя не так, как я ожидаю, но я не смог выяснить, что я настроил неправильно.
Я разместил пример проекта здесь: ExampleSpringJpaHibernatePostgresqltest с проблемой (см. ExampleTest.java
), но в итоге:
У меня есть сущности с внешним ключом следующим образом (я удалил ненужные, чтобы было легче читать):
@Entity
@Table(name = "parent")
public class ParentEntity {
@Id
@Column
private Integer id;
@Column
private String name;
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "fk_parent", referencedColumnName = "id")
private Set<ChildEntity> children;
}
@Entity
@Table(name = "child")
public class ChildEntity {
@Id
@Column
private Integer id;
@Column
private String name;
@Column(name = "fk_parent")
private Integer fkParent;
}
У меня есть тест, который использует parentRepository.findAll()
. Если я окружу этот тест с помощью @Transactional
, то тест не пройден, потому что parentEntity.getChildren()
равен нулю. Хотя без транзакции и запуска flyway clear / migrate между каждым тестом все работает как положено.
@Test
@Transactional
public void testReadWithDependencies() {
ParentEntity savedParent1 = parentRepo.save(new ParentEntity("parent1"));
childRepo.save(new ChildEntity("child1", savedParent1.getId()));
Set<ChildEntity> acutalChildren = parentRepo.findAll().get(0).getChildren();
// XXX When the tests are run with @Transactional, this assertion fails.
assertThat(acutalChildren).isNotNull();
}