{"record":{"id":"6a7fa2c275cc58fd","repo":"mybatis/mybatis-3","slug":"remove-is-not-supported-as-it-has-no-meaning-in-t","errorCode":null,"errorMessage":"Remove is not supported, as it has no meaning in the context of properties.","messagePattern":"Remove is not supported, as it has no meaning in the context of properties\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"warning","filePath":"src/main/java/org/apache/ibatis/reflection/property/PropertyTokenizer.java","lineNumber":78,"sourceCode":"  }\n\n  public String getChildren() {\n    return children;\n  }\n\n  @Override\n  public boolean hasNext() {\n    return children != null;\n  }\n\n  @Override\n  public PropertyTokenizer next() {\n    return new PropertyTokenizer(children);\n  }\n\n  @Override\n  public void remove() {\n    throw new UnsupportedOperationException(\n        \"Remove is not supported, as it has no meaning in the context of properties.\");\n  }\n}\n","sourceCodeStart":60,"sourceCodeEnd":82,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/reflection/property/PropertyTokenizer.java#L60-L82","documentation":"PropertyTokenizer implements Iterator so callers can walk the children of a dotted property path ('a.b.c'). Property paths are read-only descriptions of nested properties; removing a segment has no defined meaning, so Iterator.remove() always throws UnsupportedOperationException. This is an intentional design restriction, not a transient failure.","triggerScenarios":"Calling remove() on a PropertyTokenizer instance while iterating property paths, e.g. in generic code that treats every Iterator uniformly (frameworks, stream utilities, generic traversal helpers).","commonSituations":"Utility code that iterates-and-prunes with Iterator.remove(); adapting MyBatis property traversal into a generic collection pipeline; copy-pasted collection-manipulation code applied to a PropertyTokenizer.","solutions":["Do not call remove(); build a new property path string instead of mutating the tokenizer","Collect the segments with a while(hasNext()) next() loop and reconstruct the path you want","If generic Iterator code must run, special-case or avoid applying it to PropertyTokenizer"],"exampleFix":"// before\nIterator<PropertyTokenizer> it = new PropertyTokenizer(path);\nwhile (it.hasNext()) { it.next(); }\nit.remove(); // throws\n\n// after\nList<String> segments = new ArrayList<>();\nfor (PropertyTokenizer t = new PropertyTokenizer(path); t.hasNext(); t = t.next()) {\n  segments.add(t.getName());\n}","handlingStrategy":"validation","validationCode":"// PropertyTokenizer.remove() always throws; simply never call it.\nfor (PropertyTokenizer t = new PropertyTokenizer(path); t.hasNext(); t = t.next()) {\n  segments.add(t.getName()); // read-only traversal\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat PropertyTokenizer as a read-only cursor","In generic Iterator code, check for UnsupportedOperationException support before calling remove","Rebuild property paths from collected segments instead of mutating"],"tags":["reflection","iterator","unsupported-operation","mybatis"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}