You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven项目JCS缓存无法留存数据,请求重复走DAO层问题

Fixing JCS Cache Not Persisting Data in Your Maven Project

Hey Ashwin, let's break down why your JCS cache keeps returning empty even after the first request—there are a few critical issues in your code that are causing this behavior:

1. Mismatched Cache Keys (Biggest Culprit!)

Look at how you're storing vs retrieving data:

  • In your DAO's putIncache method, you're storing individual Album objects with numeric keys like 1, 2, 3:
    cache.put(new Integer(i+1), a);
    
  • But in your Service layer, you're trying to fetch a full list using the string key "musicCache":
    List<Album> albumList = (List) cache.get("musicCache");
    

These are completely different keys—so your cache will never find the data you stored, hence it always falls back to the DAO.

2. Reinitializing Cache Manager Every Time

Your DAO's putIncache method calls CompositeCacheManager.getUnconfiguredInstance().configure(props) on every request. This resets the entire cache configuration each time, wiping out any existing cached data.

3. Improper Cache Instance Sharing

Your Service layer uses a cache variable that's never properly initialized (or is recreated per request), and your singleton MusicCache class isn't actually being used in the Service—so the cache instance you create in the singleton isn't the one the Service checks.


Step-by-Step Fix

1. Create a Reusable Cache Utility (Single Instance)

First, make sure your JCS cache is initialized once at startup, and shared across all layers:

public class CacheUtil {
    private static JCS musicCache;

    // Initialize cache once when the class loads
    static {
        try {
            CompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance();
            Properties props = new Properties();
            
            // Basic JCS configuration (tweak based on your needs)
            props.put("jcs.default", "DC");
            props.put("jcs.default.cacheattributes", "org.apache.jcs.engine.CompositeCacheAttributes");
            props.put("jcs.default.cacheattributes.MaxObjects", "1000"); // Max objects in memory
            props.put("jcs.default.elementattributes", "org.apache.jcs.engine.ElementAttributes");
            props.put("jcs.default.elementattributes.IsEternal", "true"); // Data doesn't expire
            
            ccm.configure(props);
            musicCache = JCS.getInstance("musicCache");
        } catch (CacheException e) {
            e.printStackTrace();
            throw new RuntimeException("Failed to initialize JCS cache", e);
        }
    }

    // Get the shared cache instance
    public static JCS getMusicCache() {
        return musicCache;
    }
}

2. Fix Service Layer Logic

Rewrite your Service to properly check the cache, fetch from DAO if needed, and store the full list in cache:

public List<Album> getAllMusic() {
    // Remove repeated log4j initialization—do this once at app startup instead!
    // Properties props = new Properties();
    // props.load(new FileInputStream("src/main/resources/log4j.properties"));
    // PropertyConfigurator.configure(props);

    JCS cache = CacheUtil.getMusicCache();
    List<Album> albumList = (List<Album>) cache.get("musicCache");

    // Cache hit: return cached data
    if (albumList != null) {
        System.out.println("Returning data from cache");
        return albumList;
    }

    // Cache miss: fetch from DAO
    System.out.println("Putting data in cache");
    albumList = musicDao.getAllTopHundredMusic();

    // Store the full list in cache with the correct key
    try {
        cache.put("musicCache", albumList);
    } catch (CacheException e) {
        e.printStackTrace();
        // Even if cache fails, return the DAO data to avoid breaking the app
    }

    return albumList;
}

3. Simplify DAO Layer

Remove the putIncache method entirely—your DAO should only handle fetching data from the source (database, etc.), not managing cache:

public List<Album> getAllTopHundredMusic() {
    // Your existing logic to fetch data from database/data source
    List<Album> albumList = new ArrayList<>();
    // ... populate albumList with actual data
    return albumList;
}

Why This Works

  • Single Cache Instance: The CacheUtil initializes the cache once, so all layers use the same instance.
  • Matching Keys: We store the full List<Album> under the key "musicCache", which is exactly what the Service checks.
  • No Reinitialization: The cache manager is configured only once, so cached data persists across requests.

Testing

Now when you call http://localhost:8080/api/hello/getAllMusic:

  • First request: Prints Putting data in cache and stores the list in cache.
  • All subsequent requests: Prints Returning data from cache and returns cached data immediately.

内容的提问来源于stack exchange,提问作者Ashwin Karki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:24:47