Spring Cache - 无法获取数据列表

时间:2017-02-21 18:27:30

标签: java spring caching ehcache

我无法通过ehcache获取数据列表。

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,并找到:

  

ru.mrchebik.model.Category@f0b8277

1 个答案:

答案 0 :(得分:2)

您的设置在Ehcache和Spring级别都存在许多问题。

对于Ehcache,您的磁盘大小不应小于堆大小。有一段时间,ehcache中的分层模型意味着所有条目都必须位于磁盘层中,因此您可以通过此设置有效地将堆大小限制为磁盘大小。

在Spring方面,您使用单个缓存来容纳不同的东西,但它们会发生冲突。

  • 您的@CachePut会存储一个类别,映射到long密钥,该密钥与@CacheablefindById的密钥相匹配。
  • 但是,这会与@Cacheable上的findAll冲突,long也会使用List<Category>作为密钥,但会缓存userId。因此,categoryIdList之间的任何冲突都可能导致客户端代码中出现意外的类强制转换异常 - 期望Category获得long或相反。
  • 最后,您有两种方法,它们将两个List<Category>作为参数,但在缓存配置相同时执行不同的服务调用。该服务调用再次返回不相交的类型 - Category<input type="text" placeholder="Username or E-Mail" required data-required-message="E-Mail or Username is Required!"> 。这将引起与前一点类似的问题。

另外,我认为您希望单项缓存能够将条目神奇地附加到匹配列表中。这不会发生。

我强烈建议您查看缓存需求并更好地了解Spring抽象提供的内容......以及它不具备的内容。