{"record":{"id":"4b4191d4e87c9d61","repo":"greenrobot/greenDAO","slug":"target-entity-has-no-primary-key-but-we-need-it-f","errorCode":null,"errorMessage":"Target entity has no primary key, but we need it for ","messagePattern":"Target 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":58,"sourceCode":"    }\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":40,"sourceCodeEnd":63,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoGenerator/src/org/greenrobot/greendao/generator/ToManyWithJoinEntity.java#L40-L63","documentation":"ToManyWithJoinEntity.init3rdPass() also requires the target entity of the many-to-many relation to have a primary key, because join-entity rows must reference both sides. If targetEntity.getPropertiesPk() is empty, the generator throws this RuntimeException naming the relation.","triggerScenarios":"Adding a many-to-many relation with a join entity where the target entity has no PK properties; the source entity passed its check but the target did not.","commonSituations":"Target table designed without a primary key (e.g. pure association payload table); forgetting addIdProperty() on the target entity; legacy schema import without PKs.","solutions":["Add a primary key to the target entity (e.g. entity.addIdProperty().primaryKey())","Define a composite PK on the target entity if a single id column is not desired","Re-run the generator after updating the entity definitions","Verify with entity.getPkProperty() != null in your schema setup code"],"exampleFix":"// before\nEntity course = schema.addEntity(\"Course\"); // no PK\n// after\nEntity course = schema.addEntity(\"Course\");\ncourse.addIdProperty().primaryKey();","handlingStrategy":"validation","validationCode":"if (targetEntity.getPropertiesPk().isEmpty()) throw new IllegalStateException(\"Join-entity relation needs target PK\");","typeGuard":"function hasPk(entity) { return entity != null && entity.getPkProperty() != null; }","tryCatchPattern":"try { schema.generate(); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Target entity has no primary key\")) { addPrimaryKey(targetEntity); } else { throw e; } }","preventionTips":["Always add an id PK to entities used as relation targets","Check both source and target PKs when defining join-entity relations","Lint the schema for PK-less entities before generation"],"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"}