2017-02-21 55 views
0

我無法通過ehcache獲取數據列表。Spring Cache - 無法獲取數據列表

的servlet上下文:

<cache:annotation-driven /> 

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" 
    p:cacheManager-ref="ehcache"/> 

<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" 
     p:configLocation="/WEB-INF/spring/appServlet/ehcache.xml" p:shared="true" /> 

ehcache.xml中

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="ehcache.xsd" 
    updateCheck="true" monitoring="autodetect" dynamicConfig="true"> 
<cache name="category" 
     maxEntriesLocalHeap="5000" 
     maxEntriesLocalDisk="1000" 
     eternal="false" 
     diskSpoolBufferSizeMB="20" 
     timeToIdleSeconds="200" 
     timeToLiveSeconds="500" 
     memoryStoreEvictionPolicy="LFU" 
     transactionalMode="off"> 
    <persistence strategy="localTempSwap"/> 
</cache> 

我有類別的實體:

@Entity 
@Table(name = "categories") 
public class Category implements Serializable { 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private long categoryId; 

@Column(nullable = false) 
private String name; 

private long level; 
private long parentId; 

@ManyToMany(fetch = FetchType.EAGER, mappedBy = "categories") 
private Set<Post> posts; 

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "userId") 
private User user; 

public Category() { 
} 

public Category(User user, long level, String name, long parentId) { 
this.user = user; 
this.level = level; 
this.name = name; 
this.parentId = parentId; 
} 
// ... 
} 

然後,我嘗試緩存此方法:

@Service 
@Repository 
@Transactional 
public class CategoryServiceImpl implements CategoryService { 
@Resource 
private CategoryRepository categoryRepository; 

@Override 
@CachePut(value = "category", key = "#category.categoryId") 
public Category add(Category category) { 
    return categoryRepository.saveAndFlush(category); 
} 

@Override 
@Cacheable("category") 
public Category findById(long id) { 
    return categoryRepository.findOne(id); 
} 

@Override 
@Cacheable("category") 
public Category findByParentIdThroughCategoryId(long prntId, long userId) { 
    return categoryRepository.findByParentIdThroughCategoryId(prntId, userId); 
} 

@Override 
@Cacheable("category") 
public List<Category> findByParentId(long prntId, long userId) { 
    return categoryRepository.findByParentId(prntId, userId); 
} 

@Override 
@Cacheable("category") 
public List<Category> findAll(long userId) { 
    return categoryRepository.findAll(userId); 
} 

@Override 
@CacheEvict("category") 
public void remove(long id) { 
    categoryRepository.delete(id); 
} 
} 

當增加一個類別,然後儘量把它來查看有用戶所有類別findByParentId /的findall,它返回一個空列表

[]

它這樣做,例如我緩存的類別,然後採取類別的列表,我試圖得到類別與ID 11 - findById,並發現:

[email protected]

+0

請首先確認'categoryRepository.findAll(userId)'和'categoryRepository.findByParentId(prntId,userId)'在直接調用時會返回一些內容。另一個無關的評論是你的'CategoryServiceImpl'類不應該用'@ Repository'註釋,只有你的'CategoryRepository'應該。 – artemisian

+0

這個方法返回值。如果不成功,我不會進行緩存。 嗯...我總是這樣做@Repository和所有作品。我把'@ Repository'移到'CategoryRepository',謝謝。 – shank

+0

@artemisian我也嘗試這樣做:'@Cacheable(cacheNames =「category」,key =「#userId」)'但它沒有任何改變 – mrchebik

回答

2

你的設置有很多都在了Ehcache和Spring的水平問題。

對於Ehcache,您不應該有比堆大小更小的磁盤大小。一段時間以來,ehcache中的分層模型意味着所有條目都必須位於磁盤層中,因此使用此設置可以有效地將堆大小限制爲磁盤大小。

在Spring方面,您使用單個緩存來保存不同的內容,但它們會發生衝突。

  • @CachePut將存儲在單個類別,映射到long鍵符合你@CacheablefindById做什麼。
  • 但是,這將與衝突,也使用long作爲關鍵,但高速緩存List<Category>。因此,userIdcategoryId之間的任何衝突都可能導致客戶端代碼中發生意外的類別轉換異常 - 期望List獲得Category或相反。
  • 最後,您有兩種方法需要兩個long作爲參數,但在緩存配置相同時執行不同的服務調用。並且該服務呼叫再次返回不相交的類型 - List<Category>Category。這將導致類似的問題,在以前的觀點。

此外,我的印象是,你期望單個條目緩存神奇地追加條目匹配列表。這不會發生。

我強烈建議您檢查您的緩存需求,並更好地理解Spring抽象提供了什麼......以及它不提供什麼。

+0

謝謝,我刪除了一些可緩存的元素,並留下了2:'findByParentId'和'findAll',所以我添加了鍵:''findByParrentId-'+ #category。親Id +','+#category.user.userId「'和''findAll-'+#category.user.userId'。你怎麼說,我得到一個關於'ClassCastException:ru.mrchebik.model.Category不能轉換爲java.util.List'的異常。你能幫助我嗎,我該如何解決這個問題? – shank

+0

沒有堆棧跟蹤,很難說。可能需要一個單獨的問題。 –

+0

堆棧跟蹤:http://pastebin.com/35A14ZW9 – shank