延迟加载的集合在junit中为空

Posted

技术标签:

【中文标题】延迟加载的集合在junit中为空【英文标题】:Lazy loaded collection empty in junit 【发布时间】:2021-03-17 18:10:58 【问题描述】:

我有一个 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;

在我的服务类中,我有一个获取孩子的功能

public Set<Organisation> getChildrenForEntity(String entityId) 
    Organisation parent = organisationRepository.findByEntityIdAndActiveInd(entityId, true);
    return parent.getActiveSubOrgs();

这工作正常,并在从休息控制器调用时获取孩子,但是当我在 junit 中使用相同的函数进行测试时,它总是返回空。在我的 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());
    

测试中的子集在实际应该有circle1时为空。我曾尝试对孩子调用 Hibernate.initialize(),但这也不起作用。

【问题讨论】:

【参考方案1】:

问题是双向关系必须在双方更新,即父母和孩子必须相互了解。在您的函数setup() 中,您只需定义孩子的父母。因此,每个孩子都知道自己的父母。然而,父母并不知道它的孩子。

对于双向关系,处理此问题的一种好方法是为一个类定义一个函数来设置/添加属性并自动更新另一个类。对于OneToMany 关系,可以使用add(entity) 函数很好地处理。

public void addActiveSubOrg(Organisation activeSubOrg) 
    this.activeSubOrgs.add(activeSubOrgs);
    activeSubOrg.setParent(activeSubOrg);

【讨论】:

是的。双向更新有效。但是告诉我,我有一项服务可以以类似的方式设置父级,而不添加父级的子级。为什么它在 db 中创建了正确的条目,但不更新 java 端对象? Java 对象可以处于分离状态,即它们不反映当前数据库。我不确定您的实现中实际发生了什么。无论如何,保持双向实体始终同步以避免异常。您可以阅读 Hibernate here 中的不同状态。

以上是关于延迟加载的集合在junit中为空的主要内容,如果未能解决你的问题,请参考以下文章

hibernate延迟加载

需要在app的Documents文件夹中为图像加载延迟表图像

hibernate 延迟加载

渴望/延迟加载的成员总是为空,JPA 一对多关系

JavaWeb系列——Hibernate——延迟加载(转)

Spring Data JPA - 在没有 @Transactional 的情况下获取延迟加载的集合