2017-03-27 24 views
0

私は同じIDを持つ2つの異なるアイテム、ユーザーとグループを格納するために2つのキャッシュを用意しようとしています。私は2つの異なるキャッシュであるので、私は異なる値を得なければならないと思います。そうではありません。スプリングキャッシュ、異なるキャッシュの同じキー

@Bean 
public JedisConnectionFactory jedisConnectionFactory() { 
    LOG.debug("redis host: {}, redis port: {}", redisHost, redisPort); 
    JedisConnectionFactory factory = new JedisConnectionFactory(); 
    factory.setUseSsl(true); 
    factory.setHostName(redisHost); 
    factory.setPort(redisPort); 
    factory.setUsePool(true); 
    factory.setPassword(primaryKey); 
    return factory; 
} 

/** 
* 
* @return 
*/ 
@Bean(name = "redisTemplate") 
public RedisTemplate redisTemplate() { 
    RedisTemplate template = new RedisTemplate(); 
    template.setConnectionFactory(jedisConnectionFactory()); 
    return template; 
} 

/** 
* 
* @return 
*/ 
@Bean 
public CacheManager cacheManager() { 
    RedisCacheManager manager = new RedisCacheManager(redisTemplate()); 
    manager.setCacheNames(Arrays.asList("users", "groups")); 
    return manager; 
} 

@Cacheable(cacheNames = "users", key = "#id") 
public User findUserById(String id) { 
    return null; 
} 

@Cacheable(cacheNames = "users", key = "#user.id") 
public User updateUser(User user) { 
    return user; 
} 

@Cacheable(cacheNames = "groups", key = "#id") 
public Group findGroupById(String id) { 
    return null; 
} 

@CachePut(cacheNames = "groups", key = "#group.id") 
public Group updateGroup(Group group) { 
    return group; 
} 

JUnit。

service.removeCaches(); 

    User user = new User(); 
    user.setName("oldUser"); 
    user.setId("1"); 


    // USER 
    assertNull(service.findUserById("1")); 

    service.updateUser(user); 

    User userCached = service.findUserById("1"); 
    LOG.debug(userCached); 
    assertNotNull(userCached); 
    assertEquals(userCached.getName(), "oldUser"); 

    // GROUP 
    assertNull(service.findGroupById("1")); // <== here, im actually getting user instead of null. cache has been cleared before the test starts. 

多分私はここで異なるキャッシュの概念を誤解しています。または、異なるキーキャッシュ内でもキーが一意である必要がありますか?

ログ

Results : 

Tests in error: 
    testCache(TestRedisServiceImpl): User cannot be cast to Group 

これは基本的に、ユーザーがキャッシュから返されることを示しています。

+0

なぜあなたはグループではなくユーザーを取得していると思いますか?それを示すログはありますか? – reos

+0

あなたのコードは不完全です...あなたのJUnitの完全なコードを投稿できますか? – developer

+0

ログを追加します。 @reos – Joseph

答えて

0

実際には、CacheManager.setCacheNames()に同じキャッシュのエイリアス名を提供しますが、2つの異なるキャッシュではありません。 あなたはAPI hereを見ることができます:

無効setCacheNames(コレクションcacheNames)は、こののCacheManagerの「静的」モード用 キャッシュ名のセットを指定します。

あなたはのCacheManagerは、単に一つのキーは、(値として)一つのオブジェクトを格納するMapオブジェクトのようなものであると考えることができますので、あなたは、同じキーを持つ第2の目的を挿入しようとすると、最初のオブジェクトが置き換えられます2番目のオブジェクトと

だから、何が起こっていることは、それらの両方が同じキーで保存されているので、CacheManageruserオブジェクトがgroupオブジェクトに置き換えなっていることです。各キーはそれぞれのキャッシュ名を前に付けされ、値が置き換えられ得ることはありませんように

はCacheManagerの中にキャッシュキーを一意にするために、あなたはcacheManager.setUsePrefix()を使用することができます。

+0

ご清聴ありがとうございます。複数のキャッシュマネージャを使用することを理解していないことの1つは、データがキャッシュにどのように格納されるかです。同じIDがキャッシュシステムでどのように永続的であるか。 Webアプリケーションを再起動すると、どのデータをどのキャッシュにロードすべきかをどのように知ることができますか? usePrefixをtrueに設定すると、私のニーズにも合っています。 http://stackoverflow.com/questions/18145372/is-it-possible-to-create-multiple-cache-stores-using-springs-cache-abstraction – Joseph

+0

あなたが正しいです、あなたはキーが異なるようにusePrefixを使うことができますそれらが接頭語cachenameであるので – developer

+0

setUsePrefixが機能することを確認しましたか? – developer

関連する問題