2011-10-14 2 views
1

J'ai une entité avec une simple clé primaire longue. Je fais une requête comme: Sélectionnez à partir de la table où primary_key IN (....);Hibernate trouver par clé primaire dans la liste directe au cache L2

Hibernate semble vouloir faire une requête pour obtenir les Ids (que je viens de spécifier!), Puis aller dans le cache L2. Est-il possible d'ignorer la requête initiale? Je veux juste un ensemble d'Entités par clé primaire. Vous ne savez pas s'il s'agit d'un JPA 1 ou d'un JPA 2.0 (qui prend mieux en charge les listes).

Je peux faire findById() dans une boucle et obtenir le résultat souhaité, mais ce n'est évidemment pas optimal.

Répondre

0

Vous devrez activer query caching et cette requête spécifique en tant que mémoire cache. Ceci uniquement disponible dans JPA 2.0 via des astuces.

query.setHint(“org.hibernate.cacheable”, true); 

et activer le cache de requête en définissant la propriété suivante

hibernate.cache.use_query_cache true 

Une autre solution serait d'utiliser getReference dans une boucle et activer le chargement par lots. Si l'instance existe dans le cache, elle sera renvoyée à partir du cache - si ce n'est pas le cas lorsque le premier objet traité est accédé, une requête sera lancée pour en charger un lot. Vous pourriez cacher ceci derrière une fonction d'utilité.

public List<T> findMany(Class<T> entityClass,List<? extends Serializable> ids) { 
    List<T> result = new ArrayList<T>; 
    for(Serializable id:ids) { 
    result.add(entityManager.getRefrence(id)); 
    } 

    for(T entity:result) { 
    // force initialization of proxies, if batch loading is enabled 
    // this shouldn't lead to one query per entity 
    Hibernate.initialize(entity); 
    } 
    return result;  
} 

Ceci pourrait nécessiter quelques ajustements - ne l'ayant pas testé - en particulier la partie génériques.

+0

Je ne suis pas sûr que c'est tout. J'accepte déjà le cache de requête, et ce que je vois est que Hibernate va faire une requête: sélectionner des ids dans (ids) ce qui est un peu bête .. cache ça ... et ensuite aller chercher les entités par id ... – user671435

+0

avez-vous mis la requête spécifique en cache. De même, toute mise à jour/insertion de la même entité invalidera le cache. – gkamal

+0

Ce n'est pas le problème. Je demande des entités par ID. Toute requête mise en cache ne contiendrait que le même ensemble d'ID. Ce n'est pas que la mise en cache des requêtes ne fonctionne pas ... C'est inutile et comme vous le dites ... les mises à jour/insertions invalident le cache ... ce qui est inutile ... parce que je demande toujours des Entités par ID . Mon travail pour cela consistait à remplacer le StandardQueryCache et à le renvoyer avec le même ensemble d'IDs que j'ai passés. – user671435

Questions connexes