2011-07-15 9 views
0

J'essaie de récupérer des entités à l'aide de JPA eclipselink et je cherche un moyen de réduire le nombre de requêtes exécutées pour récupérer une seule entité. Je crois que je devrais utiliser l'annotation @JoinFetch pour récupérer des sous-entités dans la même requête que l'entité principale. Cela fonctionne bien pour un seul niveau de jointure, mais pas pour plusieurs niveaux.Comment récupérer des entités JPA imbriquées dans une seule requête

Dans l'exemple ci-dessous, EntityA contient une collection d'EntityB qui contient un EntityC. Lorsque je récupère EntityA, je veux qu'une seule requête retourne tous les 3 ensembles de données d'entité. En réalité, il génère 2 requêtes, 1 rejoignant EntityA et EntityB puis une requête séparée rejoignant EntityB et EntityC.

Est-il possible de combiner cela en une requête?

class EntityA { 
    @OneToMany(mappedBy = "entityALink", fetch = FetchType.EAGER) 
    @JoinFetch 
    private Collection<EntityB> entityBs; 
} 

class EntityB { 
    @JoinColumn(name = "X", referencedColumnName = "Y") 
    @ManyToOne(optional = false, fetch = FetchType.EAGER) 
    private EntityA entityALink; 

    @JoinColumn(name = "A", referencedColumnName = "B") 
    @ManyToOne(optional = false, fetch = FetchType.EAGER) 
    @JoinFetch 
    private EntityC entityCLink; 
} 

class EntityC { 

    @Id 
    @Basic(optional = false) 
    @Column(name = "SomeColumn") 
    private String someField 
} 

Répondre

0

Si vous avez besoin réduire le nombre de requêtes, vous pouvez à l'aide d'initialisation paresseuse - FetchType.LAZY au lieu de FetchType.EAGER - dans cette JPA façon d'obtenir des données à partir des bases de données en cas de besoin. Mais vous devez vous rappeler que cela ne fonctionne pas lorsque l'entité est déconnectée du gestionnaire. Donc, si vous envoyez cette entité à d'autres serveurs en sérialisant le formulaire (par exemple, dans une application à plusieurs niveaux), vous devez à nouveau connecter cette entité avec le gestionnaire. Si votre application s'exécute sur un serveur, vous n'avez pas ce problème. Récapitulatif n'est pas la réponse exacte à votre question, mais peut-être utile pour optimiser ce code.

La réponse exacte à votre question: Vous pouvez utiliser des requêtes nommées, mais la requête est analysée par requête SQL native, et vous n'êtes pas sûr que cela fonctionne comme vous le souhaitez. Mais peut-être que vous pouvez utiliser la méthode de requête native?

em.createNativeQuery("SELECT ... your queries") 

Pour cette purpuse s'il vous plaît vous lisez sur l'annotation @SqlResultSetMapping pour configurer la classe d'entités résultat ...

+0

Mon objectif principal ici est de charger un ensemble de données très important au démarrage de l'application dans aussi rapide une fois que possible et pas besoin de retourner à la base de données par la suite. La récupération paresseuse ne fait que retarder le problème jusqu'à ce que les données soient requises. L'approche jusqu'à présent consiste à utiliser des annotations d'entité pour spécifier des jointures, mais je me demande maintenant si les requêtes nommées fourniraient une meilleure solution. – insano10

+0

Si vous ne voulez pas utiliser de requête native, peut-être préférable d'utiliser les vues de base de données, et créer une autre entité avec des champs A et B? Mais ce n'est pas résoudre le problème avec plusieurs à une multiplicité. Cependant, il peut être simplifié à une seule vue dans votre cas? – wojand

+0

Merci pour les suggestions. À la fin, j'ai résolu ce problème en utilisant des requêtes et la récupération paresseux. Au lieu de m'attendre à ce que JPA retourne toutes les données que je voulais en une fois (ce qui était beaucoup trop lent), j'ai opté pour mon DAO pour appeler 2 requêtes séparées et assembler les données. Les liens entre les entités sont maintenant paresseux au lieu d'être désireux et il appartient aux requêtes de déterminer combien de données sont ramenées. J'utilise eclipselink et j'ai donc pu spécifier des conseils pour optimiser les jointures entre les tables. – insano10

Questions connexes