jeecgboot/JeecgBoot · error · RuntimeException
DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!
Error message
DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!
What it means
Thrown by FreemarkerParseFactory.parseTemplate when the caller's parameter map already contains the key 'DaoFormat' (MINI_DAO_FORMAT constant). The method needs to inject its own SimpleFormat helper under that exact key, so a collision is treated as a programming error. It is wrapped/rethrown as a generic '解析SQL模板异常' RuntimeException.
Source
Thrown at jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/dynamic/db/FreemarkerParseFactory.java:99
return false;
}
return true;
}
/**
* 解析ftl模板
*
* @param tplName 模板名
* @param paras 参数
* @return
*/
public static String parseTemplate(String tplName, Map<String, Object> paras) {
try {
log.debug(" minidao sql templdate : " + tplName);
StringWriter swriter = new StringWriter();
Template mytpl = TPL_CONFIG.getTemplate(tplName, ENCODE);
if (paras.containsKey(MINI_DAO_FORMAT)) {
throw new RuntimeException("DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!");
}
paras.put(MINI_DAO_FORMAT, new SimpleFormat());
mytpl.process(paras, swriter);
String sql = getSqlText(swriter.toString());
paras.remove(MINI_DAO_FORMAT);
return sql;
} catch (Exception e) {
log.error(e.getMessage(), e.fillInStackTrace());
log.error("发送一次的模板key:{ " + tplName + " }");
//System.err.println(e.getMessage());
//System.err.println("模板名:{ "+ tplName +" }");
throw new RuntimeException("解析SQL模板异常");
}
}
/**
* 解析ftl
*View on GitHub (pinned to 96fb33f5ec)
Solutions
- Rename the conflicting business parameter to something other than 'DaoFormat'.
- Build a fresh HashMap for each minidao call instead of reusing/mutating a shared map.
- Strip the reserved key defensively before calling parseTemplate: paras.remove("DaoFormat").
- Document the reserved key in your DAO layer so future params avoid it.
Example fix
// before
Map<String,Object> paras = new HashMap<>();
paras.put("DaoFormat", "report"); // reserved!
FreemarkerParseFactory.parseTemplate("userList.ftl", paras);
// after
paras.put("format", "report");
FreemarkerParseFactory.parseTemplate("userList.ftl", paras); Defensive patterns
Strategy: validation
Validate before calling
if (paras.containsKey("DaoFormat")) paras.remove("DaoFormat");
FreemarkerParseFactory.parseTemplate(tplName, paras); Type guard
public static boolean noReservedKeys(Map<String,Object> p){ return p == null || !p.containsKey("DaoFormat"); } Try / catch
try { FreemarkerParseFactory.parseTemplate(t, p); }
catch (RuntimeException e) { log.error("template {} failed: {}", t, e.getMessage()); } Prevention
- Namespace business param keys to avoid minidao internals.
- Build a fresh map per DAO call.
- Document reserved keys for DAO authors.
When it happens
Trigger: A minidao DAO method receives a parameter Map that was built with a key literally named 'DaoFormat', or a copy/merge of two maps accidentally carried the reserved key over. Common in custom minidao SQL templates and report SQL templating.
Common situations: Developer named a real business field 'daoFormat'/'DaoFormat'; a generic map-merge utility duplicated keys across parameter sources; a template param builder reused a static map without clearing.
Related errors
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/e7c8a136fb539412.
Report an issue: GitHub.