{"record":{"id":"825b215e5ce84a29","repo":"greenrobot/greenDAO","slug":"source-entity-has-no-primary-key-but-we-need-it-f-825b21","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/ToManyWithJoinEntity.java","lineNumber":54,"sourceCode":"    }\n\n    public Entity getJoinEntity() {\n        return joinEntity;\n    }\n\n    public Property getSourceProperty() {\n        return sourceProperty;\n    }\n\n    public Property getTargetProperty() {\n        return targetProperty;\n    }\n\n    void init3rdPass() {\n        super.init3rdPass();\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        List<Property> pks2 = targetEntity.getPropertiesPk();\n        if (pks2.isEmpty()) {\n            throw new RuntimeException(\"Target entity has no primary key, but we need it for \" + this);\n        }\n    }\n\n}\n","sourceCodeStart":36,"sourceCodeEnd":63,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoGenerator/src/org/greenrobot/greendao/generator/ToManyWithJoinEntity.java#L36-L63","documentation":"ToManyWithJoinEntity.init3rdPass() requires the source entity of the many-to-many relation to have a primary key so the join entity can reference it. If sourceEntity.getPropertiesPk() is empty, the generator throws this RuntimeException naming the relation.","triggerScenarios":"Adding a many-to-many relation with a join entity (ToManyWithJoinEntity) where the source entity defines no PK properties and generation reaches the 3rd pass.","commonSituations":"Join-table modeling where one side table was created without a primary key; forgetting addIdProperty() on the source entity; schema evolution that dropped a PK column.","solutions":["Add a primary key to the source entity (e.g. entity.addIdProperty().primaryKey())","Or define a composite PK covering the columns you have via addXxxProperty().primaryKey() on multiple properties","Re-run generation after fixing the entity definition","Check both sides — the next check (target entity) has the same requirement"],"exampleFix":"// before\nEntity student = schema.addEntity(\"Student\"); // no PK\n// after\nEntity student = schema.addEntity(\"Student\");\nstudent.addIdProperty().primaryKey();","handlingStrategy":"validation","validationCode":"if (sourceEntity.getPropertiesPk().isEmpty()) throw new IllegalStateException(\"Join-entity relation needs source PK\");","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\")) { addPrimaryKey(sourceEntity); } else { throw e; } }","preventionTips":["Give both sides of many-to-many relations primary keys before defining the join entity","Run a pre-generation schema lint checking every entity has a PK","Document PK requirements when sharing generator setup code"],"tags":["greendao","codegen","many-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"}