2017-07-19 38 views
1

我有這些實體,它不是來自真實的代碼,但它並不重要,我認爲。從JPA嵌套OneToMany關係獲取單個元素

@Entity 
    public class Country{ 

     private String name; 
     //other fields with getters and setters 
     @OneToMany 
     private List<City> cites; 


    } 

    @Entity 
    public class City { 

     private String name; 
     //other fields with getters and setters 
     @OneToMany 
     private List<Employee> emps;//list size could be millions 


    } 

    @Entity 
    public class Employee { 

     private String name; 
     //other fields with getters and setters 

     @OneToMany 
     private List<Cars> cars;// list size could be 1000 

    } 


    @Entity 
    public class Car { 
     private String name; 

     @ManyToOne 
     private Employee emp; 
    } 

我想獲得一個汽車實體,但與其它數據以及(國家,城市,員工)這樣

1國家在1市,其中1 Empoyee其中1車(其ID我把選擇)

所以,當我做JPA從國家加入像

select c from Country c 
inner join c.cites ci 
inner join ci.emps em 
    inner join ci.cars car where car.id = ? 

我得到了全國所有數據(所有城市)。

我該怎麼做1個國家,1個城市,1個員工,1輛車。

如果這不可能做一個jpa查詢,然後請建議其他方式。

所有關係都是雙向和懶惰的。

I tried this way. 
1)select car by id. then get Id of employee from car. 
2)select Employee by id - but at this point Employee data are nulls - 

我認爲這是因爲從汽車到員工的ManyToOne是懶惰的。你怎麼看 ?

回答

2

只需選擇附加實體你想:

select c, ci, em, car from Country c 
inner join c.cites ci 
inner join ci.emps em 
inner join ci.cars car where car.id = ? 

或者,由於您的聯繫是雙向的,選擇汽車:它有一個多對一它的員工,這將有多對一以其城市,將與該國一個多對一:

select car from Car car where car.id = ? 

或者乾脆

em.find(Car.class, carId); 

,現在你可以做

car.getEmployee().getCity().getCountry() 
+0

非常感謝。 對於這兩種解決方案我都必須這樣做。 emp.setCars(Collections.sigltonlist(轎車)) city.setEmps(Collections.singletonList(EMP)) country.setCiyes(Collections.singletonList(市)) 期間JSON serializtion否則懶惰收藏逐漸加入百萬數據的。 另外第二個解決方案在ManyToOne懶時不起作用(在這種情況下數據是空值) – user1321466

+0

不,不這樣做。修改託管實體會自動使更改在數據庫中保持不變。你真的不想移除該國的所有城市等。即使該實體沒有管理,那麼這只是在你的應用程序中顯示設計問題。你正在序列化爲JSON的不是一個擁有城市的國家。這是查詢的結果,包含國家,城市等的局部視圖。只需創建一個適當的類,其中包含您真正想要序列化的實際數據,並由REST資源返回。 –

+0

謝謝你,我認爲在選擇實體沒有管理後 - 這就是爲什麼我沒有得到數據庫更新。但我明白你在說什麼。因此,您認爲以單一員工身份返回單一城市是錯誤的。 etc ... – user1321466

2

如果所有的關係都是雙向的,那麼我會建議從Car開始,然後提取層次結構。

select c from Car car 
    inner join fetch car.emp emp 
    inner join fetch emp.city city 
    inner join fetch city.country country 
where car.id = ? 

請記住在所有您錯過的連接中添加fetch

+0

非常感謝。 但我也有做 emp.setCars(Collections.sigltonlist(轎車)) city.setEmps(Collections.singletonList(EMP)) country.setCiyes(Collections.singletonList(市)) 然後只返回縣城對象來自Spring控制器 否則,在json序列化期間,所有懶惰集合都會填充數百萬個數據 – user1321466