gpt4 book ai didi

java - 双向 @ManyToMany JSON 映射的无限递归

转载 作者:行者123 更新时间:2023-12-01 10:42:24 28 4
gpt4 key购买 nike

我有以下场景:有公司和员工。每个公司都有一组员工。每个员工可以为多家公司工作。所以我实现了以下关系:

公司类别:

@JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "employee_id") )
@ManyToMany(fetch = FetchType.LAZY)
private Set<Employee> employees;

员工类别:

@JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "employee_id") , inverseJoinColumns = @JoinColumn(name = "company_id") )
@ManyToMany(fetch = FetchType.EAGER)
private Set<Company> companies;

目标是能够获取 List<Employee> ,每个员工都有 Set<Company> ,或其他场景,获取 List<Company> ,但没有获取相关的 Set<Employee> 。但如果我获取 Company按 ID,相关 Set<Employee>还应该获取。

我在 daos 中做了什么:如果我在这两种情况下获取列表,它会按预期工作而不会出现问题:急切的内容 - 被获取,惰性的内容 - 不被获取。要通过 id 获取 Employee,我执行以下操作,它获取一个不为空 Set<Company> 的 Employee ,正如我所期望的:

public Employee find(Long id) {
Employee employee = entityManager.find(Employee.class, id);
return employee;

通过 id 不为空的 Set<Employee> 获取公司我尝试过:

变体1:

public Company find(Long id) {
TypedQuery<Company> query = em.createQuery("select distinct e from Company e left outer join fetch e.employees where e.company_id=:company_id", Company.class);
query.setParameter("company_id", id);
Company company = query.getSingleResult();
return company;
}

变体2:

 public Company find(Long id) {
Company company = entityManager.find(Company.class, id);
Hibernate.initialize(company.getEmployees());
return company;
}

正如我所看到的,variant1 和variant2 都给出 org.springframework.http.converter.HttpMessageNotWritableException由于 JSON 序列化过程中的无限递归。我尝试使用 @JsonManagedReference@JsonBackReference ,但然后设置注释为 @JsonBackReference无论任何 join fetch 都永远不会被获取或Hibernate.initialize我用。那么实现我需要的正确方法是什么?谢谢。

最佳答案

看来我找到了一个解决方案:使用@JsonIdentityInfo。更多信息here现在我的实体看起来像这样(删除了所有不相关的字段和方法),并且它们完全按照我需要的方式工作:

公司类别:

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="company_id")
public class Company {
@JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "employee_id") )
@ManyToMany(fetch = FetchType.LAZY)
private Set<Employee> employees;
}

员工类别:

 @Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="employee_id")
public class Employee {
@JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "employee_id") , inverseJoinColumns = @JoinColumn(name = "company_id") )
@ManyToMany(fetch = FetchType.EAGER)
private Set<Company> companies;
}

我希望它能对某人有所帮助。

更新1实际上,正如尼尔·斯托克顿(Neil Stockton)所注意到的,映射并不完全正确,并且不是合法的双向。所以我只是更改了如下所示的实体之一,然后不需要额外的注释来避免无限递归

     @Entity
public class Employee {
@ManyToMany(fetch = FetchType.EAGER, mappedBy="employees")
private Set<Company> companies;
}

我认为这是重要的更新。

关于java - 双向 @ManyToMany JSON 映射的无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34375577/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com