繁体   English   中英

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

[英]Infinite recursion on JSON mapping of bidirectional @ManyToMany

我有以下情况:有公司和员工。 每个公司都有一组员工。 每个员工可以为多家公司工作。 因此,我实现了以下关系:

公司类别:

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

Employee.class:

@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>每个Employee或另一种方案来获取List<Company> ,但不获取相关的Set<Employee> 但是,如果我通过ID提取Company ,则还应该提取相关的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;
        }

如我所见,由于JSON序列化过程中的无限递归,所以variant1和variant2都给出了org.springframework.http.converter.HttpMessageNotWritableException 我尝试使用@JsonManagedReference@JsonBackReference ,但是无论如何我使用的任何联接join fetchHibernate.initialize都不会获取带有@JsonBackReference注释的Set。 那么实现我所需的正确方法是什么? 谢谢。

看来我找到了解决方案:使用@JsonIdentityInfo 更多信息这里现在我的实体看起来像(删除所有不相关的领域和方法),而他们正是上班我需要他们:

公司类别:

@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:

 @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;
     }

我认为这是重要的更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM