2010-08-25 45 views
12

J'utilise Hibernate 3.5.1 et EntityManager pour la persistance des données (avec JPA 2.0 et EHCache 1.5). Je peux obtenir la requête par le code suivant:HIbernate Entity Manager: Comment mettre en cache des requêtes?

EntityManager em; 
... 
Query query = em.createQuery(...); 
... 

Maintenant, le problème est que la méthode CreateQuery de EntityManager() retourne javax.persistence.Query qui, contrairement org.hibernate.Query (retourné par CreateQuery du SessionFactory() méthode), n'a pas la méthode org.hibernate.Query.setCacheable().

Comment puis-je donc mettre en cache les requêtes avec EntityManager (ou une autre partie d'Hibernate)?

Répondre

24

Vous pouvez utiliser la méthode unwrap pour obtenir l'implémentation du fournisseur lorsque vous souhaitez utiliser des extensions spécifiques au fournisseur. par exemple,

org.hibernate.Query hquery = query.unwrap(org.hibernate.Query.class); 

Ensuite, vous pouvez travailler avec l'interface spécifique au fournisseur. Alternativement, vous pouvez simplement déballer votre EntityManager à Session avant de créer la requête.

Si vous ne voulez pas avoir des importations de mise en veille prolongée dans votre code, vous pouvez aussi faire

query.setHint("org.hibernate.cacheable", Boolean.TRUE); 

vraiment à vous de quelle manière vous préférez présenter la dépendance des fournisseurs.

Je préférerais le premier car il échouera avec une exception si Hibernate est enlevé de vos dépendances en envoyant un grand rouge "Hey vous développeur changeant ceci, il y avait une dépendance de fournisseur ici." Alors que l'indice ne fait simplement rien s'il n'est pas compris par le fournisseur.

D'autres personnes préféreraient tolérer que les chaînes magiques dépendant du fournisseur dans le code aient besoin d'avoir une dépendance du fournisseur au moment de la compilation.

+1

Merci pour les conseils. J'utiliserai les "chaînes magiques spécifiques au vendeur" avec une chaîne importée d'une classe de support constante (comme HibernateHintConstants), ce qui garantira qu'une erreur de compilation est générée si je supprime Hibernate (à condition que je rappelle d'enlever la classe avec les constantes aux astuces spécifiques à Hibernate). – eold

+4

@leden - Les chaînes sont déjà dans org.hibernate.ejb.QueryHints, pour éviter de réinventer la roue. – OrangeDog

+0

Vous pouvez également ajouter des astuces dans les annotations @NamedQuery – OrangeDog