2017-06-13 1 views
2

J'utilise Spring Cache, où je passe dans une collection de clés, et le retour est une liste d'entités. Je voudrais que le cadre de mise en cache comprenne que chaque élément de la liste de retour doit être mis en cache avec le code correspondant. Pour l'instant, il semble que la clé soit la liste entière, et si une clé me ​​manque dans l'appel suivant, elle va essayer de recharger toute la collection.Spring Cache avec la collection d'éléments/entités

@Override 
@Cacheable(value = "countries") 
public List<Country> getAll(List<String>codes) { 
    return countryDao.findAllInCodes(codes); 
} 

Une autre possibilité est que le retour est une carte, de même je voudrais que le cache soit assez intelligent pour ne demande pour les articles qui ont jamais été interrogés avant, aussi de les mettre en cache chaque élément avec sa clé.

@Override 
@Cacheable(value = "countries") 
public Map<String,Country> getAllByCode(List<String>codes) { 
    return countryDao.findAllInCodes(codes); 
} 

On suppose la classe pays ressemble à ceci:

class Country{ 
    String code; 
    String fullName; 
    long id; 

... // getters setters constructurs etc.. 
} 

Est-ce possible avec Spring Cache?

+0

Pourquoi ne pas utiliser le deuxième niveau de JPA? Le cache de printemps est vraiment impuissant et les erreurs sont susceptibles d'être utilisées pour la mise en cache par rapport à la bibliothèque JPA ou Cache comme EhCache. – davidxxx

+0

@davidxxx autant que je sache, Spring Cache est juste une abstraction, et EhCache peut être l'implémentation ci-dessous. La différence est qu'il supprime le besoin d'écrire toute logique de mise en cache au-delà de l'annotation. Comment écrirais-je le code ci-dessus avec JPA? – Charbel

Répondre

1

En fait, il est possible, même avec Spring's Caching Abstraction, mais pas out-of-the-box (OOTB). Essentiellement, vous devez personnaliser infrastructure de mise en cache du printemps (expliqué plus loin)

Par défaut, infrastructure de mise en cache de printemps utilise l'ensemble des arguments des paramètres de la méthode @Cacheable comme le cache « clé », comme expliqué here. Bien sûr, vous pouvez également personnaliser la résolution de clé en utilisant soit Spel Expression ou avec une implémentation personnalisée KeyGenerator, comme expliqué here.

encore, que ne le fait pas rupture de la collection ou un tableau de arguments de paramètres avec valeur de retour de la méthode @Cacheable dans les entrées du cache individuelles (par exemple des paires clé/valeur sur la base du tableau/collection ou Carte) .

Pour cela, vous avez besoin d'une implémentation personnalisée de Printemps CacheManager (en fonction de votre stratégie de mise en cache/fournisseur) et Cache interfaces.

NOTE: Ironie du sort, ce sera la 3ème fois que j'ai répondu à peu près la même question, d'abord here, puis here et maintenant ici, :-). En tout cas ...

J'ai mis à jour/nettoyé my example (un peu) pour cette annonce.

Notez que my example extends and customizes le ConcurrentMapCacheManager fourni dans le Spring Framework lui-même.

Théoriquement, vous pouvez étendre/personnaliser toute mise en œuvre CacheManager, comme pour Redis en printemps données Redis, here (source), ou Pivotal Spring GemFire ​​deCacheManager dans données GemFire ​​, here (source). La version open source de Pivotal GemFire ​​ est Apache Geode, qui a un projet printemps données Geode correspondant, (source for CacheManager dans données Spring Geode, qui est essentiellement identique à SD GemFire). Bien sûr, vous pouvez appliquer cette technique à d'autres fournisseurs de cache ... Hazelcast, ehcache, etc.

Cependant, les véritables entrailles du travail est assuré par les custom implementation (ou les mœurs spécifiquement, le base class) de printempsCache interface.

Quoi qu'il en soit, espérons-le de my example, vous serez en mesure de comprendre ce que vous devez faire dans votre application pour satisfaire aux exigences de mise en cache de votre application.

En outre, vous pouvez appliquer la même approche à la gestion Maps, mais je vais laisser cela comme un exercice pour vous, ;-).

Espérons que cela aide!

Cheers, John

+0

Merci @John Je vais y jeter un coup d'oeil et essayer de l'implémenter pour mes besoins! – Charbel