gpt4 book ai didi

java - 添加 @Transactional 通过阻止 JPA 获取外键来破坏单元测试

转载 作者:行者123 更新时间:2023-11-29 12:50:21 25 4
gpt4 key购买 nike

我正在尝试提高飞路数据库测试的速度。最初的方法是在每次测试运行之间运行 flyway.clear()flyway.migrate()。但问题是现在我们有一些可能会长时间运行的飞路迁移脚本,我们不想在每次测试之间重新运行这些脚本。

我一直在尝试使用spring的@Transactional注解在每次测试后回滚数据库,那么我们只需要跑一次flyway就可以了。

问题是,一旦我围绕测试添加事务,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();
}

最佳答案

parentRepo.findAll 不会从数据库中刷新数据,您也不会将子项添加到父项中的子项中。

因此没有子实体分配给父实体。

因此,如果您刷新实体(我注入(inject)了 EntityManger),您的测试就会成功:

@Test
@Transactional
public void testReadWithDependencies() {
assertThat(parentRepo.findAll()).isEmpty();
assertThat(childRepo.findAll()).isEmpty();

ParentEntity savedParent1 = parentRepo.save(new ParentEntity("parent1"));
childRepo.save(new ChildEntity("child1", savedParent1.getId()));

List<ParentEntity> allParents = parentRepo.findAll();
assertThat(allParents).hasSize(1);

// Refresh
ParentEntity parentEntity = allParents.get(0);
entityManager.refresh(parentEntity);

Set<ChildEntity> acutalChildren = parentEntity.getChildren();

// XXX When the tests are run with @Transactional, this assertion fails.
assertThat(acutalChildren).isNotNull();

assertThat(acutalChildren).hasSize(1);
assertThat(acutalChildren.iterator().next().getName()).isEqualTo("child1");
}

关于java - 添加 @Transactional 通过阻止 JPA 获取外键来破坏单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55501079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com