[英]Infinite recursion on JSON mapping of bidirectional @ManyToMany
I have following scenario: There are companies and employees. 我有以下情况:有公司和员工。 Each company has a set of employees.
每个公司都有一组员工。 Each employee can work for several companies.
每个员工可以为多家公司工作。 So I implemented following relationships:
因此,我实现了以下关系:
Company.class: 公司类别:
@JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "employee_id") )
@ManyToMany(fetch = FetchType.LAZY)
private Set<Employee> employees;
Employee.class: Employee.class:
@JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "employee_id") , inverseJoinColumns = @JoinColumn(name = "company_id") )
@ManyToMany(fetch = FetchType.EAGER)
private Set<Company> companies;
The goal is the ability to fetch List<Employee>
, each Employee with Set<Company>
, or another scenario, to fetch List<Company>
, but without fetching related Set<Employee>
. 目标是能够获取
List<Employee>
,具有Set<Company>
每个Employee或另一种方案来获取List<Company>
,但不获取相关的Set<Employee>
。 But if I fetch a Company
by id, related Set<Employee>
should also be fetched. 但是,如果我通过ID提取
Company
,则还应该提取相关的Set<Employee>
。
What I did in daos: If I fetch Lists in both cases, it work as supposed to work without issues: what is eager - is fetched, what is lazy - is not fetched. 我在daos中所做的事情:如果我在两种情况下都获取列表,则它可以正常工作而不会出现问题:渴望的东西-被获取,懒惰的东西-不被获取。 To fetch Employee by id I do following, and it fetches an Employee with not empty
Set<Company>
, as I expect it to: 要通过id来获取Employee,我会执行以下操作,并且它会获取一个不为空
Set<Company>
的Employee,正如我期望的那样:
public Employee find(Long id) {
Employee employee = entityManager.find(Employee.class, id);
return employee;
To fetch Company by id with not empty Set<Employee>
I tried: 要通过ID获取具有不为空的
Set<Employee>
我尝试过:
variant 1: 变体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;
}
variant2: 变体2:
public Company find(Long id) {
Company company = entityManager.find(Company.class, id);
Hibernate.initialize(company.getEmployees());
return company;
}
As I see both variant1 and variant2 give org.springframework.http.converter.HttpMessageNotWritableException
due to the infinite recursion during JSON serialization. 如我所见,由于JSON序列化过程中的无限递归,所以variant1和variant2都给出了
org.springframework.http.converter.HttpMessageNotWritableException
。 I tried to use @JsonManagedReference
and @JsonBackReference
, but then Set annotated with @JsonBackReference
is never fetched regarless any join fetch
or Hibernate.initialize
I use. 我尝试使用
@JsonManagedReference
和@JsonBackReference
,但是无论如何我使用的任何联接join fetch
或Hibernate.initialize
都不会获取带有@JsonBackReference
注释的Set。 So what is the correct approach to implement what I need? 那么实现我所需的正确方法是什么? Thank you.
谢谢。
It seems I found a solution: using @JsonIdentityInfo
. 看来我找到了解决方案:使用
@JsonIdentityInfo
。 More information here Now my entities look like that (removed all unrelated fields and methods), and they work exactly as I need them to: 更多信息这里现在我的实体看起来像(删除所有不相关的领域和方法),而他们正是上班我需要他们:
Company.class: 公司类别:
@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;
}
Employee.class: Employee.class:
@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;
}
I hope it will help to somebody. 我希望这会对某人有所帮助。
UPDATE 1 Actually, as Neil Stockton noticed, the mapping is not quite correct and is not legal bidirectional. 更新1实际上,正如尼尔·斯托克顿(Neil Stockton)所注意到的,该映射不是很正确,并且不是合法的双向映射。 So I just changed one of entities like below, then no additional annotations needed to avoid infinite recursion
因此,我只是更改了如下所示的实体之一,然后不需要附加注释来避免无限递归
@Entity
public class Employee {
@ManyToMany(fetch = FetchType.EAGER, mappedBy="employees")
private Set<Company> companies;
}
I think it's important update. 我认为这是重要的更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.