Hey today i found out that my Repository-Test runs perfectly fine when i use the @SpringBootTest
-Annotation. But when i switch it to @DataJpaTest
-Annotation, my @OneToMany
-Annotated Collection of child elements is null.
Here an example:
ParentEntity.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
@Repository
public interface ParentRepository extends JpaRepository<ParentEntity, Integer> {
@EntityGraph(value = "parent.childs")
Optional<ParentEntity> findById(Integer id);
}
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
@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
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. The resulting hibernate query contains the left outer join that i would expect. 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
There is explained what the cause of the problem is:
The parent
And to solve this problem: