{"record":{"id":"78e03b64540abbf9","repo":"greenrobot/greenDAO","slug":"source-properties-do-not-match-target-properties","errorCode":null,"errorMessage":"Source properties do not match target properties: ","messagePattern":"Source properties do not match target properties: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"DaoGenerator/src/org/greenrobot/greendao/generator/ToMany.java","lineNumber":60,"sourceCode":"    }\n\n    public Property[] getTargetProperties() {\n        return targetProperties;\n    }\n\n    void init2ndPass() {\n        super.init2ndPass();\n        if (sourceProperties == null) {\n            List<Property> pks = sourceEntity.getPropertiesPk();\n            if (pks.isEmpty()) {\n                throw new RuntimeException(\"Source entity has no primary key, but we need it for \" + this);\n            }\n            sourceProperties = new Property[pks.size()];\n            sourceProperties = pks.toArray(sourceProperties);\n        }\n        int count = sourceProperties.length;\n        if (count != targetProperties.length) {\n            throw new RuntimeException(\"Source properties do not match target properties: \" + this);\n        }\n\n        for (int i = 0; i < count; i++) {\n            Property sourceProperty = sourceProperties[i];\n            Property targetProperty = targetProperties[i];\n\n            PropertyType sourceType = sourceProperty.getPropertyType();\n            PropertyType targetType = targetProperty.getPropertyType();\n            if (sourceType == null || targetType == null) {\n                throw new RuntimeException(\"Property type uninitialized\");\n            }\n            if (sourceType != targetType) {\n                System.err.println(\"Warning to-one property type does not match target key type: \" + this);\n            }\n        }\n    }\n\n    void init3rdPass() {","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoGenerator/src/org/greenrobot/greendao/generator/ToMany.java#L42-L78","documentation":"ToMany.init2ndPass() checks that the number of source join properties equals the number of target join properties; the generated JOIN/IN clause pairs them positionally. When sourceProperties.length != targetProperties.length the relation is malformed and the generator throws this RuntimeException.","triggerScenarios":"Calling setSourceProperties/setTargetProperties (or a constructor variant) on a ToMany with lists of different lengths, e.g. two source columns against one target column.","commonSituations":"Composite-key relation where only one side's columns were specified; typo passing the same list twice with different filters; refactoring one entity's key columns without updating the other.","solutions":["Make the source and target property lists the same length, pairing columns positionally","Use the simple addToMany(targetEntity, targetProperty) overload for single-column relations","For composite keys, pass matching counts on both sides (e.g. 2 source PKs and 2 target FKs)","Print both lists during generation setup to confirm the pairing"],"exampleFix":"// before\ntoMany.setSourceProperties(srcA, srcB); // 2 sources\ntoMany.setTargetProperties(tgtA);       // 1 target -> mismatch\n// after\ntoMany.setTargetProperties(tgtA, tgtB); // 2 targets, paired positionally","handlingStrategy":"validation","validationCode":"if (sourceProps.size() != targetProps.size()) throw new IllegalArgumentException(\"ToMany source/target property counts differ\");","typeGuard":"function countsMatch(src, tgt) { return Array.isArray(src) && Array.isArray(tgt) && src.length === tgt.length; }","tryCatchPattern":"try { schema.generate(); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Source properties do not match target\")) { comparePropertyLists(); } else { throw e; } }","preventionTips":["Use the simple single-property addToMany overload unless composite keys are required","Keep composite source/target lists in adjacent code so lengths are visually checkable","Add a unit test asserting list lengths in your generator setup"],"tags":["greendao","codegen","to-many","property-mismatch"],"backgroundTag":"invalid-argument-value","analyzedSha":"0bbb338e17c4cf28aba5aae62d42f73f50186157","analyzedAt":"2026-09-08T03:22:36.050Z","contentChangedAt":"2026-09-08T03:22:36.050Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}