简体   繁体   English

为什么 EntityGraph 不能与 DataJpaTest 一起使用?

[英]Why is EntityGraph not working with DataJpaTest?

Hey today i found out that my Repository-Test runs perfectly fine when i use the @SpringBootTest -Annotation.嘿,今天我发现当我使用@SpringBootTest -Annotation 时,我的 Repository-Test 运行得非常好。 But when i switch it to @DataJpaTest -Annotation, my @OneToMany -Annotated Collection of child elements is null.但是当我将它切换到@DataJpaTest -Annotation 时,我的@OneToMany -Annotated 子元素集合是 null。

Here an example:这里有一个例子:

ParentEntity.class父实体.class

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@NamedEntityGraph(name="parent.childs", attributeNodes = @NamedAttributeNode("childEntities"))
@Table(name = "parent")
public class ParentEntity {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    Integer id;

    @OneToMany(mappedBy = "parentId")
    Collection<ChildEntity> childEntities;

}

ParentRepository.class ParentRepository.class

@Repository
public interface ParentRepository extends JpaRepository<ParentEntity, Integer> {
    @EntityGraph(value = "parent.childs")
    Optional<ParentEntity> findById(Integer id);
}

ChildEntity.class ChildEntity.class

@Data
@Entity
@Table(name = "child")
public class ChildEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", nullable = false)
    private Integer id;
    
    @Column(name = "parentId", nullable = false, insertable = false, updatable = false)
    private Integer parentId;

    @ManyToOne@JoinColumn(name = "parentId", referencedColumnName = "id", nullable = false)
    private ParentEntity parentEntity;

}

ChildRepository.class ChildRepository.class

@Repository
public interface ChildRepository extends JpaRepository<ChildEntity, Integer> {
}

And this is the Test:这是测试:

@SpringBootTest
@AutoConfigureTestDatabase
public class RepoTest {
    @Autowired
    ParentRepository parentRepository;

    @Autowired
    ChildRepository childRepository;

    @Commit
    @Rollback(false)
    @Test
    void test(){
        /* arrange */
        ParentEntity parent = new ParentEntity();
        var parentId = parentRepository.save(parent).id;

        ChildEntity child = new ChildEntity();
        child.setParentEntity(parent);
        childRepository.save(child);

        /* act */
        /* Yes, i know there should be an exists()-check but lets keep it simple */
        ParentEntity returnedParent = parentRepository.findById(parentId).get();

        /* assert */
        assertThat(returnedParent.getChildEntities()).hasSize(1);
    }
}

This test works as expected.此测试按预期工作。

But when i change the @SpringBootTest -Annotation to @DataJpaTest , the childEntities-Field of the ParentEntity.class stays null但是当我将@SpringBootTest -Annotation 更改为@DataJpaTest时,ParentEntity.class 的childEntities-Field保持为null

I tried to delombok the code and find the cause by debugging each step of the query but i couldnt make it out right now.我试图通过调试查询的每个步骤来 delombok 代码并找到原因,但我现在无法弄清楚。 The resulting hibernate query contains the left outer join that i would expect.结果 hibernate 查询包含我期望的左外连接。 So my guess is that the error has to do with Data-Binding.所以我的猜测是错误与数据绑定有关。 Maby some type of (auto-)configuration is not loaded when i run the test with the other annotation.当我使用其他注释运行测试时,可能不会加载某种类型的(自动)配置。

I am very interested in the cause, so I would appreciate an explanation我对原因很感兴趣,所以我很感激解释

After a lot of further research, i found the following helpful link:经过大量的进一步研究,我发现了以下有用的链接:

Spring Data Jpa Test returns null list even after child is saved Spring 数据 Jpa 测试返回 null 即使孩子被保存

There is explained what the cause of the problem is:解释了问题的原因是什么:

The parent父母

gets not loaded for the database but from the internal cache.不是为数据库加载而是从内部缓存加载。

And to solve this problem:并解决这个问题:

You need to write a FlushAndClear method您需要编写一个 FlushAndClear 方法

   @PersistenceContext
   private EntityManager em;

   private void flushAndClear() {
      em.flush();
      em.clear();
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM