2015-12-19 40 views
0

我有以下場景:有公司和員工。每家公司都有一組員工。每個員工都可以爲幾家公司工作。所以,我實現了以下關係式:雙向JSON映射的無限遞歸@ManyToMany

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:

@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>。但如果我通過id獲取Company,則還應該獲取相關的Set<Employee>

我在daos中做了什麼: 如果我在兩種情況下獲取Lists,它的工作原理應該沒有問題:什麼是渴望 - 被提取,什麼是懶惰 - 不會被提取。 獲取由ID我做以下的員工,並獲取與非空Set<Company>一名員工,我期待它:

變種:

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

VARIANT2:

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

正如我所見,由於JSON序列化過程中的無限遞歸,變體1和變體2都給出org.springframework.http.converter.HttpMessageNotWritableException。 我試圖用@JsonManagedReference@JsonBackReference,但然後設置註釋@JsonBackReference永遠不會取任何無瑕join fetchHibernate.initialize我使用。 那麼實施我所需要的正確方法是什麼?謝謝。

+0

如果這種關係是雙向的,那麼「mappedBy」? –

+0

@NeilStockton這是錯誤的方式來實現?它工作正常。我是否應該等待由於此實施而出現的一些問題? –

+1

它不是雙向的,沒有mappedBy。目前你有2個1-N關係,沒有聯繫 –

回答

1

看來我找到了解決辦法:用@JsonIdentityInfo。更多信息here 現在我的實體看起來像(刪除所有不相關的領域和方法),而他們正是工作,我需要他們:

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:

@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 其實,尼爾·斯托克頓注意到,映射是不太正確的,是不合法的雙向的。所以,我只是改變了類似下面的實體之一,則不需要額外的註解來避免無限遞歸

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

我認爲這是很重要的更新。

+0

感謝您的更新 - 它解決了我的問題:) - 我仍然從一方得到stackoverflow錯誤..我甚至使用FetchType.Lazy都沒有結果 –