延迟加载的集合在 junit 中为空
Lazy loaded collection empty in junit
我有一个 SpringBoot 应用程序,我在其中定义了一个实体,如下所示
@Entity
public class Organisation {
@Id
@GeneratedValue
@JsonIgnore
private Long id;
private String entityId;
@OneToMany(mappedBy = "parent")
@Where(clause = "active_ind=true")
@JsonIgnore
private Set<Organisation> activeSubOrgs = new HashSet<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentId")
private Organisation parent;
public Set<Organisation> getActiveSubOrgs() {
return activeSubOrgs;
}
在我的服务中 class 我有一个函数可以获取 children
public Set<Organisation> getChildrenForEntity(String entityId) {
Organisation parent = organisationRepository.findByEntityIdAndActiveInd(entityId, true);
return parent.getActiveSubOrgs();
}
这工作正常并在从 rest 控制器调用时得到 children,但是当我使用相同的函数在 junit 中测试时,它总是 returns 为空。在我的 sql 跟踪日志中,我看到调用 getActiveSubOrgs() 时未触发查询。我的 junit 测试如下
@SpringBootTest
@RunWith(SpringRunner.class)
@Transactional
public class OrgServiceTest {
@Autowired
private OrganisationService organisationService;
@Before
public void setup() {
Organisation company = new Organisation("c", true);
company = organisationRepository.save(company);
Organisation circle = new Organisation("circle1", true);
circle.setParent(company);
circle = organisationRepository.save(circle);
Organisation div1 = new Organisation("div1", true);
div1.setParent(circle);
div1 = organisationRepository.save(div1);
}
@Test
public void getChildrenForEntitySuccessTest() {
Set<Organisation> children = organisationService.getChildrenForEntity("c");
System.out.println(children.iterator().next().getEntityId());
assertEquals("circle1", children.iterator().next().getEntityId());
}
测试中的children集是空的,而实际上应该有circle1。我试过在 children 上调用 Hibernate.initialize(),但这也不起作用。
问题是双向关系必须在双方更新,即 parent 和 children 必须相互了解。在您的函数 setup()
中,您只需定义 child 的 parent。因此,每个 child 都知道其 parent。但是,parent不知道它的children。
对于双向关系,处理这个问题的一个好方法是为一个 class 到 set/add 一个 属性 定义一个函数并自动更新另一个。在 OneToMany
关系的情况下,可以使用 add(entity)
函数很好地处理。
public void addActiveSubOrg(Organisation activeSubOrg) {
this.activeSubOrgs.add(activeSubOrgs);
activeSubOrg.setParent(activeSubOrg);
}
我有一个 SpringBoot 应用程序,我在其中定义了一个实体,如下所示
@Entity
public class Organisation {
@Id
@GeneratedValue
@JsonIgnore
private Long id;
private String entityId;
@OneToMany(mappedBy = "parent")
@Where(clause = "active_ind=true")
@JsonIgnore
private Set<Organisation> activeSubOrgs = new HashSet<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentId")
private Organisation parent;
public Set<Organisation> getActiveSubOrgs() {
return activeSubOrgs;
}
在我的服务中 class 我有一个函数可以获取 children
public Set<Organisation> getChildrenForEntity(String entityId) {
Organisation parent = organisationRepository.findByEntityIdAndActiveInd(entityId, true);
return parent.getActiveSubOrgs();
}
这工作正常并在从 rest 控制器调用时得到 children,但是当我使用相同的函数在 junit 中测试时,它总是 returns 为空。在我的 sql 跟踪日志中,我看到调用 getActiveSubOrgs() 时未触发查询。我的 junit 测试如下
@SpringBootTest
@RunWith(SpringRunner.class)
@Transactional
public class OrgServiceTest {
@Autowired
private OrganisationService organisationService;
@Before
public void setup() {
Organisation company = new Organisation("c", true);
company = organisationRepository.save(company);
Organisation circle = new Organisation("circle1", true);
circle.setParent(company);
circle = organisationRepository.save(circle);
Organisation div1 = new Organisation("div1", true);
div1.setParent(circle);
div1 = organisationRepository.save(div1);
}
@Test
public void getChildrenForEntitySuccessTest() {
Set<Organisation> children = organisationService.getChildrenForEntity("c");
System.out.println(children.iterator().next().getEntityId());
assertEquals("circle1", children.iterator().next().getEntityId());
}
测试中的children集是空的,而实际上应该有circle1。我试过在 children 上调用 Hibernate.initialize(),但这也不起作用。
问题是双向关系必须在双方更新,即 parent 和 children 必须相互了解。在您的函数 setup()
中,您只需定义 child 的 parent。因此,每个 child 都知道其 parent。但是,parent不知道它的children。
对于双向关系,处理这个问题的一个好方法是为一个 class 到 set/add 一个 属性 定义一个函数并自动更新另一个。在 OneToMany
关系的情况下,可以使用 add(entity)
函数很好地处理。
public void addActiveSubOrg(Organisation activeSubOrg) {
this.activeSubOrgs.add(activeSubOrgs);
activeSubOrg.setParent(activeSubOrg);
}