{"record":{"id":"8abdfb0399dccab2","repo":"greenrobot/greenDAO","slug":"source-entity-has-no-primary-key-but-we-need-it-f","errorCode":null,"errorMessage":"Source entity has no primary key, but we need it for ","messagePattern":"Source entity has no primary key, but we need it for ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"DaoGenerator/src/org/greenrobot/greendao/generator/ToMany.java","lineNumber":53,"sourceCode":"\n    public Property[] getSourceProperties() {\n        return sourceProperties;\n    }\n\n    public void setSourceProperties(Property[] sourceProperties) {\n        this.sourceProperties = sourceProperties;\n    }\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            }","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoGenerator/src/org/greenrobot/greendao/generator/ToMany.java#L35-L71","documentation":"ToMany.init2ndPass() requires the source entity of a to-many relation to have a primary key, because the generated join query filters target rows by the source entity's PK columns. When sourceProperties was not explicitly set and the source entity has no PK properties, the generator aborts with this RuntimeException naming the relation.","triggerScenarios":"Creating a ToMany relation (entity.addToMany) where the source entity defines no primary key and no explicit sourceProperties are supplied via setSourceProperties/setOrderBy.","commonSituations":"Generating an entity from a legacy table without a primary key; forgetting .primaryKey() on the source entity's id property; schema copied from a NoSQL design into greenDAO.","solutions":["Add a primary key to the source entity (e.g. entity.addIdProperty().primaryKey())","Explicitly set source properties for the relation via toMany.setSourceProperties(...) matching target properties","If the source table genuinely has no PK, add one (even a composite or synthetic column) before generating","Verify entity.getPropertiesPk() returns the intended PK by checking the entity definition"],"exampleFix":"// before\nEntity user = schema.addEntity(\"User\"); // no PK\nEntity note = schema.addEntity(\"Note\");\nuser.addToMany(note, note.getUserId());\n// after\nEntity user = schema.addEntity(\"User\");\nuser.addIdProperty().primaryKey();\nuser.addToMany(note, note.getUserId());","handlingStrategy":"validation","validationCode":"if (sourceEntity.getPropertiesPk().isEmpty()) throw new IllegalStateException(\"Source entity needs a PK before addToMany\");","typeGuard":"function hasPk(entity) { return entity != null && entity.getPkProperty() != null; }","tryCatchPattern":"try { schema.generate(); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Source entity has no primary key\")) { fixSchemaDefinition(e.getMessage()); } else { throw e; } }","preventionTips":["Always call addIdProperty().primaryKey() on entities used as ToMany sources","Validate all entities have PKs before running the generator","Review legacy table definitions for missing PKs"],"tags":["greendao","codegen","to-many","primary-key"],"backgroundTag":"missing-required-config-field","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"}