休眠多个@OneToMany 关系在父关系中生成更多结果

我将从结果开始。在下一张图片中,我将显示 company.userAccount 的结果内容。在数据库中,我只有两家公司分配给同一个用户,其中一家公司有 7 项服务。

http://img1.mukewang.com/64928a8c0001b24105310242.jpg

@Entity

@Table(name = "user_account")

@Data

@Introspected

@JsonIgnoreProperties(value = {"id"})

public class UserAccount {

    ...


    @OneToMany(mappedBy = "userAccount", fetch = FetchType.EAGER)

    private List<Company> companies = new ArrayList<>();


}



@Entity

@Table(name = "company")

@Data

@Introspected

@ToString(exclude = {"userAccount"})

@JsonIgnoreProperties(value = {"id", "userAccount"})

public class Company {

    ...


    @ManyToOne(optional = false)

    @JoinColumn(name = "user_account_id", updatable = false, nullable = false)

    private UserAccount userAccount;


}



@Entity

@Table(name = "service")

@Data

@Introspected

@ToString(exclude = {"company"})

@JsonIgnoreProperties(value= {"id", "company"})

public class Service {

    ...


    @ManyToOne(optional = false)

    @JoinColumn(name = "company_id", updatable = false, nullable = false)

    private Company company;


}



@Transactional

public Service saveService(@Valid @Uuid UUID companyUuid, SaveServiceCommand command) {

    Company company = companyRepository.getCompanyByUuid(companyUuid).orElseThrow(() -> new NoSuchElementException("unrecognized company"));


    Service service = new Service();

    service.setCompany(company);

    service.setName(command.getName());

    service.setUuid(UUID.randomUUID().toString());


    return companyRepository.saveCompanyService(service);

}


@Transactional

public Service saveCompanyService(@Valid Service service) {

    entityManager.persist(service);

    return service;

}

生成的查询(简化)是


select * from user_account a left outer join company c on a.id=c.user_account_id left outer join service s on c.id=s.company_id; 

这将产生

http://img1.mukewang.com/64928a99000110d302390211.jpg

预期结果:我期望在 UserAccount 中只看到 2 家公司,其中一家公司有 6 项服务。为什么我会有这个结果?为什么同一个公司对象多次出现在列表中?我怎样才能避免这种情况?

我相信一种解决方案是将 @OneToMany 关系的获取类型更改为 LAZY (因为它们是默认的)(已经测试了该解决方案并且它有效),但是如果我需要这种类型的场景怎么办?


森林海
浏览 107回答 1
1回答

杨__羊羊

是的,有两家公司,就像你说的那样。您可以注意到,所有对象都是相同的(哈希值匹配)。其背后的原因是该查询为一家公司生成 6 行,并且PersistenceBaghibernate 使用的查询默认情况下不会删除重复项。传递distinct给你的 sql 是行不通的,因为只有一个父实体。但这可以通过使用hibernate的查询提示来实现。传递QueryHints.HINT_PASS_DISTINCT_THROUGH给 yourQuery只是删除重复的子项。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java