2009-11-18 14 views
0

Nous implémentons une page Web pour maintenir une structure organisationnelle. La structure est stockée dans SQL Server 2008 et utilise le nouveau type de données HierarchyID. Étant donné que nous avons eu des problèmes pour faire jouer JPA et Hibernate avec ce nouveau type de données, nous avons décidé d'utiliser des vues et des procédures stockées pour extraire ce type de données. Nous voulons donc utiliser une procédure stockée pour persister dans nos entités, mais comment le faire avec JPA n'est pas clair.Persistance de SQL Server 2008 en utilisant des procédures stockées, JPA et Hibernate

Premièrement, prenons-nous la bonne approche et deuxièmement, est-il possible d'utiliser des procédures stockées pour persister des entités annotées avec JPA?

Répondre

1

Nous avons choisi une approche où nous utilisons des requêtes natives pour appeler des procédures stockées chaque fois que nous devons gérer le type de données d'ID de hiérarchie. Cela nous a permis d'éviter tout SQL propriétaire tout en bénéficiant du nouveau type de données.Notre compréhension, et les résultats initiaux, est que l'ID de hiérarchie nous permet d'agréger des données à travers une structure arborescente simplement en demandant à tous les descendants d'un nœud donné.

Par exemple, pour obtenir un compte de toutes les commandes à travers un « n » structure de la profondeur des régions, les bureaux, les magasins et les ministères pourraient utiliser quelque chose comme ce qui suit:

SELECT COUNT(Orders) FROM Orders WHERE NodeOrderedAt.IsDescendantOf(@Node) 

@ ChssPly76 Merci pour les références à la deux modèles. Je les lirai plus tard :)

1

Tout d'abord, prenons-nous la bonne approche [...]

Eh bien, ça dépend. Si cela ne vous dérange pas d'être lié à votre moteur de base de données alors je suppose qu'il n'est pas totalement faux de vouloir bénéficier de fonctionnalités propriétaires comme HierarchyID. Mais vous ne doivent utiliser les nouvelles fonctionnalités ...

d'autre part, est-il possible d'utiliser des procédures stockées pour persister des entités annotées avec JPA?

A ma connaissance, aucune . Vous pouvez appeler la procédure stockée en utilisant des "requêtes natives" (voir @NamedNativeQuery et/ou EntityManager#createNativeQuery()) mais vous ne pouvez pas les utiliser pour persister des entités, du moins pas avec JPA. Si cela ne vous dérange pas d'utiliser les extensions Hibernate, jetez un oeil à @SQLInsert(callable=true, ...) (voir le chapitre 2.4.11. Custom SQL for CRUD operations de la documentation des annotations Hibernate).


Personnellement, je trouve qu'il est très compliqué de créer des vues, des procédures stockées et de traiter les extensions de JPA juste utiliser HierarchyID. Les nouvelles fonctionnalités sont cool ... quand ils simplifient les choses, pas quand ils ajoutent plus de complexité est le cas ici. En d'autres termes, en utilisant HierarchyID ne résout vraiment rien, je pense que je préfère coller avec une colonne classique parent_id (et cela rendra le processus de modification du moteur de base de données plus lisse, même si c'est un événement très improbable).

+0

Grand +1 sur tout ce qui précède; et il ne suffit pas d'insérer/mettre à jour - ** n'importe quelle requête traitant de HierarchyID devrait être écrite comme SQL. On dirait plus de problèmes que ça en vaut la peine. Comme un petit aparté - 'parent_id' n'est pas le moyen de mapper des hiérarchies :-) – ChssPly76

+0

@ ChssPly76 Un grand merci :) Pour ma culture, qu'est-ce qui me manque dans les hiérarchies parent/enfant? Je doute maintenant mais je n'ai pas trouvé de réponse à http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-parentchild.html. Faites le moi savoir pour que je puisse réparer cette partie. –

+0

Oh, ce n'est pas spécifique à l'hibernation. Le mappage des hiérarchies via 'parentId' est appelé 'modèle de liste d'adjacence'. Il a ses utilisations dans certaines circonstances particulières mais globalement est plutôt inefficace. Le «modèle de jeu imbriqué» est sans doute une approche bien meilleure, bien qu'un peu plus complexe et moins performant dans les opérations de «déplacement». Vous pouvez google l'un ou l'autre pour plus de détails. – ChssPly76

0

Vous pouvez utiliser ce @Pascal suggéré ou vous pouvez également utiliser

@org.hibernate.annotations.NamedNativeQuery(
    callable=true, 
    name="queryname", 
    readOnly=true, 
    query="call sproc_name(?,:param)", 
    resultSetMapping="your_result_mapping" 
) 

voir javadoc pour la liste complète des options

Le seul problème avec cette approche est que le paramètre out (si vous en avez besoin) doit être premier et doit générer un refcursor.

Voir aussi this (il fait référence aux fonctions mais peut être modifié pour les sprocs). Ces exemples sont basés sur Oracle, mais la chaîne d'appel est facilement modifiée pour MSSQl.

Je ne sais pas beaucoup de HierarchyId est-il possible de représenter en tant que Hibernate UserType ou l'un des types?

+0

J'ai mentionné une requête native mais ... cela ne répond pas au * est-il possible d'utiliser des procédures stockées pour les entités ** persistantes ** annotées avec la partie JPA *. –

Questions connexes