2017-07-19 2 views
1

J'ai ces entités, Ce n'est pas du vrai code, mais ce n'est pas important je pense.Obtenir un seul élément de la relation OneToMany JPA imbriquée

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

Je voudrais obtenir seule entité de voiture, mais avec d'autres données, ainsi (pays, ville, employés) comme celui-ci

1 Pays dans lequel 1 Ville dans laquelle 1 Empoyee dans lequel 1 voiture (qui Id je mets sélection)

Alors, quand je JPA arrive de pays comme

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

Je reçois tOUTES les données de pays (avec toutes les villes).

Que dois-je faire pour obtenir 1 pays, 1 ville, 1 employé, 1 voiture.

Si cela n'est pas possible avec une requête jpa, veuillez suggérer un autre moyen.

Toutes les relations sont bidirectionnelles et paresseuses. Je pense que c'est parce que ManyToOne de Car to Employee est paresseux. Qu'est-ce que tu penses ?

Répondre

2

sélectionner uniquement les entités supplémentaires que vous voulez:

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 = ? 

Ou, puisque vos associations sont bi-directionnel, sélectionnez la voiture: il aura un ManyToOne à son employé, ce qui aura un ManyToOne avec sa ville, aura un ManyToOne avec son pays:

select car from Car car where car.id = ? 

ou simplement

em.find(Car.class, carId); 

et maintenant vous pouvez le faire

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

Merci beaucoup. Pour les deux solutions, je dois faire. emp.setCars (Collections.sigltonlist (voiture)) city.setEmps (Collections.singletonList (emp)) country.setCiyes (Collections.singletonList (ville)) Sinon, pendant JSON serializtion toutes les collections paresseux se peuplaient avec des millions de données. Aussi la deuxième solution ne fonctionne pas lorsque ManyToOne est Lazy (les données sont nulls dans ce cas) – user1321466

+0

Non, non, ne faites pas cela. La modification d'une entité gérée rendra automatiquement les modifications persistantes dans la base de données. Vous ne voulez vraiment pas supprimer toutes les villes du pays, etc. Et même si l'entité n'est pas gérée, cela montre simplement un problème de conception dans votre application. Ce que vous numérotez en JSON n'est pas un pays avec ses villes. C'est le résultat d'une requête, qui contient une vue partielle des pays, des villes, etc. Il suffit de créer une classe appropriée contenant les données réelles que vous voulez réellement sérialiser, et qui sont renvoyées par votre ressource REST. –

+0

Merci, je pense que certaines entités ne sont pas gérées - c'est pourquoi je ne reçois pas de mise à jour en DB. Mais je comprends ce que vous dites. Donc, à votre avis, il est mauvais de retourner Pays avec une seule ville qui contient un seul employé. etc ... – user1321466

2

Si toutes les relations sont bidirectionnelles, je suggérerais de partir de Car, puis d'aller chercher la hiérarchie.

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 = ? 

Rappelez-vous simplement d'ajouter que fetch dans toutes les jointures que vous avez manqué.

+0

Merci beaucoup. mais je dois aussi faire emp.setCars (Collections.sigltonlist (voiture)) city.setEmps (Collections.singletonList (emp)) country.setCiyes (Collections.singletonList (ville)) Alors seulement retourner l'objet comté à partir du contrôleur Spring Sinon pendant json serializtion toutes les collections paresseuses sont peuplées avec des millions de données – user1321466