greenrobot/greenDAO · error · RuntimeException
Currently only single FK columns are supported:
Error message
Currently only single FK columns are supported:
What it means
ToOne.init3ndPass() builds the foreign-key column list for a to-one relation. greenDAO's generator only supports a single FK column: if fkProperties has more than one entry, or the target entity has no PK property at all, it throws this RuntimeException naming the relation.
Solutions
- Use a single-column primary key on the target entity and a single FK property on the source
- Remove extra fkProperties so only one remains, or use entity.addToOne(targetEntity, singleFkProperty)
- If you need composite references, use a ToMany or model the join explicitly with an intermediate entity
- Ensure the target entity has a PK (addIdProperty().primaryKey()) before the relation's 3rd pass
Example fix
// before ToOne toOne = order.addToOne(customer, null); toOne.setFkProperties(custRegionProp, custCodeProp); // 2 FKs // after ToOne toOne = order.addToOne(customer, order.getCustomerIdProperty()); // single FK
Defensive patterns
Strategy: validation
Validate before calling
if (targetEntity.getPkProperty() == null || fkProps.size() > 1) throw new IllegalStateException("ToOne requires single FK and single-PK target"); Type guard
function singleFkValid(fkProps, target) { return Array.isArray(fkProps) && fkProps.length === 1 && target.getPkProperty() != null; } Try / catch
try { schema.generate(); } catch (RuntimeException e) { if (e.getMessage().startsWith("Currently only single FK columns")) { simplifyRelation(e.getMessage()); } else { throw e; } } Prevention
- Never call setFkProperties with multiple properties on a ToOne
- Ensure relation targets use single-column primary keys
- Model composite-key references with ToMany or an explicit join entity instead
When it happens
Trigger: Calling setFkProperties with more than one property on a ToOne; or creating a ToOne to a target entity that has no primary key (getPkProperty() returns null); a ToOne defined against a composite-key target.
Common situations: Modeling a to-one relation to an entity with a composite primary key; copying ToMany composite-key patterns onto a ToOne; target entity defined without addIdProperty().primaryKey().
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Property does not exist in
- Type is already non-primitive
- No mapping for
- Source entity has no primary key, but we need it for
- Source properties do not match target properties:
AI-assisted analysis of greenrobot/greenDAO@0bbb338e17 (2026-09-08).
Data as JSON: /api/errors/832a685944c3f3d2.
Report an issue: GitHub.
Appendix: source
Thrown at DaoGenerator/src/org/greenrobot/greendao/generator/ToOne.java:93
public boolean isUseFkProperty() {
return useFkProperty;
}
void init2ndPass() {
if (name == null) {
char[] nameCharArray = targetEntity.getClassName().toCharArray();
nameCharArray[0] = Character.toLowerCase(nameCharArray[0]);
name = new String(nameCharArray);
}
}
/** Constructs fkColumns. Depends on 2nd pass of target key properties. */
void init3ndPass() {
Property targetPkProperty = targetEntity.getPkProperty();
if (fkProperties.length != 1 || targetPkProperty == null) {
throw new RuntimeException("Currently only single FK columns are supported: " + this);
}
Property property = fkProperties[0];
PropertyType propertyType = property.getPropertyType();
if (propertyType == null) {
propertyType = targetPkProperty.getPropertyType();
property.setPropertyType(propertyType);
// Property is not a regular property with primitive getters/setters, so let it catch up
property.init2ndPass();
property.init3ndPass();
} else if (propertyType != targetPkProperty.getPropertyType()) {
System.err.println("Warning to-one property type does not match target key type: " + this);
}
resolvedKeyJavaType[0] = schema.mapToJavaTypeNullable(propertyType);
resolvedKeyUseEquals[0] = checkUseEquals(propertyType);
}
protected boolean checkUseEquals(PropertyType propertyType) {View on GitHub (pinned to 0bbb338e17)