{"record":{"id":"bc8ff8f12e553a3d","repo":"mybatis/mybatis-3","slug":"cache-ref-not-yet-resolved","errorCode":null,"errorMessage":"Cache-ref not yet resolved","messagePattern":"Cache-ref not yet resolved","errorType":"exception","errorClass":"IncompleteElementException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java","lineNumber":208,"sourceCode":"    ResultMapping resultMapping = buildResultMapping(resultType, null, column, javaType, jdbcType, null, null, null,\n        null, typeHandler, new ArrayList<>(), null, null, false);\n    Map<String, String> namespaceDiscriminatorMap = new HashMap<>();\n    for (Map.Entry<String, String> e : discriminatorMap.entrySet()) {\n      String resultMap = e.getValue();\n      resultMap = applyCurrentNamespace(resultMap, true);\n      namespaceDiscriminatorMap.put(e.getKey(), resultMap);\n    }\n    return new Discriminator.Builder(configuration, resultMapping, namespaceDiscriminatorMap).build();\n  }\n\n  public MappedStatement addMappedStatement(String id, SqlSource sqlSource, StatementType statementType,\n      SqlCommandType sqlCommandType, Integer fetchSize, Integer timeout, String parameterMap, Class<?> parameterType,\n      String resultMap, Class<?> resultType, ResultSetType resultSetType, boolean flushCache, boolean useCache,\n      boolean resultOrdered, KeyGenerator keyGenerator, String keyProperty, String keyColumn, String databaseId,\n      LanguageDriver lang, String resultSets, boolean dirtySelect, ParamNameResolver paramNameResolver) {\n\n    if (unresolvedCacheRef) {\n      throw new IncompleteElementException(\"Cache-ref not yet resolved\");\n    }\n\n    id = applyCurrentNamespace(id, false);\n\n    MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)\n        .resource(resource).fetchSize(fetchSize).timeout(timeout).statementType(statementType)\n        .keyGenerator(keyGenerator).keyProperty(keyProperty).keyColumn(keyColumn).databaseId(databaseId).lang(lang)\n        .resultOrdered(resultOrdered).resultSets(resultSets)\n        .resultMaps(getStatementResultMaps(resultMap, resultType, id)).resultSetType(resultSetType)\n        .flushCacheRequired(flushCache).useCache(useCache).cache(currentCache).dirtySelect(dirtySelect)\n        .paramNameResolver(paramNameResolver);\n\n    ParameterMap statementParameterMap = getStatementParameterMap(parameterMap, parameterType, id);\n    if (statementParameterMap != null) {\n      statementBuilder.parameterMap(statementParameterMap);\n    }\n\n    MappedStatement statement = statementBuilder.build();","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java#L190-L226","documentation":"Thrown by addMappedStatement() when the flag unresolvedCacheRef is still true: this mapper's <cache-ref> could not be resolved yet, so statements must not be cached with a null/stale cache. It is an IncompleteElementException, so the whole mapped statement is deferred and rebuilt on a later parse pass once the referenced cache exists.","triggerScenarios":"A mapper with <cache-ref namespace=\"X\"/> where X's cache is not yet registered when the mapper's <select>/<insert>/... elements are processed; the statement build aborts here and the incomplete statement is queued for retry.","commonSituations":"Normal cross-mapper cache-ref ordering at startup (usually resolves on retry), or a permanent failure combining a dangling cache-ref with statements — the final error surfaced to the user is typically this one at the end of configuration parsing.","solutions":["Fix the underlying cache-ref: make sure the referenced namespace exists and declares a cache (see errors 22/23)","Check that the referenced mapper file is included in the configuration before relying on its cache","As a workaround while isolating the problem, temporarily replace cache-ref with a local <cache/> declaration"],"exampleFix":"<!-- before: CommonMapper.xml has no cache -->\n<cache-ref namespace=\"com.acme.CommonMapper\"/>\n<!-- after: declare a cache in CommonMapper.xml -->\n<cache/>","handlingStrategy":"validation","validationCode":"// Verify all cache-ref namespaces resolved after factory build\nConfiguration cfg = factory.getConfiguration();\n// incomplete refs are gone only when resolved; assert none linger:\nif (!cfg.getIncompleteCacheRefs().isEmpty()) {\n  throw new IllegalStateException(\"Unresolved cache-refs: \" + cfg.getIncompleteCacheRefs());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare the shared cache in the least-dependent (base) mapper so refs always resolve","Treat any 'Cache-ref not yet resolved' surfacing at runtime as a startup config bug — fix the cache-ref, do not catch it"],"tags":["mybatis","cache","cache-ref","statement","incomplete-element"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}