Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 添加@Transactional会阻止JPA获取外键,从而破坏单元测试_Java_Postgresql_Hibernate_Jpa_Transactional - Fatal编程技术网

Java 添加@Transactional会阻止JPA获取外键,从而破坏单元测试

Java 添加@Transactional会阻止JPA获取外键,从而破坏单元测试,java,postgresql,hibernate,jpa,transactional,Java,Postgresql,Hibernate,Jpa,Transactional,我正试图提高flyway数据库测试的速度。最初的方法是在每次测试运行之间运行flyway.clear()和flyway.migrate()。但问题是现在我们有一些潜在的长时间运行的flyway迁移脚本,我们不想在每次测试之间重新运行这些脚本 我一直在尝试在每次测试后使用spring@Transactional注释回滚数据库,然后我们只需要运行flyway一次 问题是,只要我在测试周围添加事务,JPA就会停止获取外键。我假设这是因为嵌套事务的行为与我预期的不一样,但我无法找出我配置错误的地方 我在

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

我一直在尝试在每次测试后使用spring@Transactional注释回滚数据库,然后我们只需要运行flyway一次

问题是,只要我在测试周围添加事务,JPA就会停止获取外键。我假设这是因为嵌套事务的行为与我预期的不一样,但我无法找出我配置错误的地方

我在这里发布了一个示例项目:有问题(请参见
ExampleTest.java
),但总结如下:

我有如下带有外键的实体(我已删除了不必要的内容以使其更易于阅读):

@实体
@表(name=“parent”)
公共类父实体{
@身份证
@纵队
私有整数id;
@纵队
私有字符串名称;
@OneToMany(fetch=FetchType.EAGER)
@JoinColumn(name=“fk\u parent”,referencedColumnName=“id”)
私人儿童;
}
@实体
@表(name=“child”)
公共类子实体{
@身份证
@纵队
私有整数id;
@纵队
私有字符串名称;
@列(name=“fk_父项”)
父级的私有整数;
}
然后我有一个使用
parentRepository.findAll()
的测试。如果我使用
@Transactional
环绕该测试,则测试失败,因为
parentEntity.getChildren()
为空。但是,如果没有事务,并且在每个测试之间运行flyway clear/migrate,一切都会按预期工作

@测试
@交易的
public void testReadWithDependencies(){
ParentEntity savedParent1=parentRepo.save(新ParentEntity(“parent1”));
save(新的ChildEntity(“child1”,savedParent1.getId());
设置acutalChildren=parentRepo.findAll().get(0.getChildren();
//XXX使用@Transactional运行测试时,此断言失败。
assertThat(acutalChildren).isNotNull();
}

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

因此,不存在分配给父实体的子实体

因此,如果刷新实体(我注入了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");
}
@测试
@交易的
public void testReadWithDependencies(){
资产(parentRepo.findAll()).isEmpty();
资产(childRepo.findAll()).isEmpty();
ParentEntity savedParent1=parentRepo.save(新ParentEntity(“parent1”));
save(新的ChildEntity(“child1”,savedParent1.getId());
列出allParents=parentRepo.findAll();
资产(所有父母)。hasSize(1);
//刷新
ParentEntity ParentEntity=allParents.get(0);
entityManager.refresh(父实体);
设置acutalChildren=parentEntity.getChildren();
//XXX使用@Transactional运行测试时,此断言失败。
assertThat(acutalChildren).isNotNull();
资产(acutalChildren).hasSize(1);
断言(acutalChildren.iterator().next().getName()).isEqualTo(“child1”);
}

主键是如何生成的?它们是使用hibernate序列生成器生成的,请看我发布到github的示例,我刚刚删除了该代码以使文章易于阅读。当然非常感谢。如此简单,令人尴尬。如果一个额外的问题是可以的,有没有一种方法可以在查询时自动刷新实体?我只会将其应用于测试配置文件。据我所知,没有。但是您应该正确设置测试中的所有依赖项,以避免此类问题