{"record":{"id":"73da14808418d929","repo":"mybatis/mybatis-3","slug":"error-deserializing-object-cause-cause","errorCode":null,"errorMessage":"Error deserializing object.  Cause: ${cause}","messagePattern":"Error deserializing object\\.  Cause: (.+?)","errorType":"exception","errorClass":"CacheException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/cache/decorators/SerializedCache.java","lineNumber":105,"sourceCode":"  private byte[] serialize(Serializable value) {\n    try (ByteArrayOutputStream bos = new ByteArrayOutputStream();\n        ObjectOutputStream oos = new ObjectOutputStream(bos)) {\n      oos.writeObject(value);\n      oos.flush();\n      return bos.toByteArray();\n    } catch (Exception e) {\n      throw new CacheException(\"Error serializing object.  Cause: \" + e, e);\n    }\n  }\n\n  private Serializable deserialize(byte[] value) {\n    SerialFilterChecker.check();\n    Serializable result;\n    try (ByteArrayInputStream bis = new ByteArrayInputStream(value);\n        ObjectInputStream ois = new CustomObjectInputStream(bis)) {\n      result = (Serializable) ois.readObject();\n    } catch (Exception e) {\n      throw new CacheException(\"Error deserializing object.  Cause: \" + e, e);\n    }\n    return result;\n  }\n\n  public static class CustomObjectInputStream extends ObjectInputStream {\n\n    public CustomObjectInputStream(InputStream in) throws IOException {\n      super(in);\n    }\n\n    @Override\n    protected Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {\n      return Resources.classForName(desc.getName());\n    }\n\n  }\n\n}","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/cache/decorators/SerializedCache.java#L87-L123","documentation":"Thrown by SerializedCache.deserialize() when converting the cached byte[] back into an object fails: class not found on deserialization (stale cache across a redeploy), stream corruption, serialVersionUID mismatch, or a JEP 290 filter rejection. Note the entry point runs SerialFilterChecker.check() first and the actual read happens inside CustomObjectInputStream, so class-loading and filter failures surface here.","triggerScenarios":"Reading a second-level cache entry (getObject) whose bytes were written by a previous deployment: entity class renamed/moved (ClassNotFoundException), class evolved without compatible serialVersionUID (InvalidClassException), cache storage (e.g. Redis/Ehcache disk) surviving application restarts, or deserialization filters blocking a class.","commonSituations":"Rolling deploys with a shared distributed cache where old-format entries linger; JDK upgrades tightening ObjectInputFilter defaults; repackaging entities to a new module/package; corrupted entries after a network cache hiccup.","solutions":["Clear/flush the second-level cache after deployments that change entity classes (or version the cache keys with an app version prefix)","Declare explicit serialVersionUID on cached types to survive compatible field changes","Align JEP 290 filter configuration with the classes you intentionally cache; evict the offending key and retry"],"exampleFix":"// before: stale entry from previous deploy -> InvalidClassException\n\n// after: cache keys namespaced by app version\ncacheKeyPrefix = \"app:v42:\"; // bump on entity changes -> old entries never deserialized","handlingStrategy":"fallback","validationCode":"null","typeGuard":null,"tryCatchPattern":"catch (CacheException e) { if (e.getCause() instanceof InvalidClassException || e.getCause() instanceof ClassNotFoundException) { evict(key); return loadFromDatabaseAndRepopulate(); } throw e; }","preventionTips":["Version cache keys per deployment to avoid stale entries","Declare serialVersionUID on cached types","Flush distributed caches during rolling deploys"],"tags":["mybatis","second-level-cache","deserialization","deployment"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}