greenrobot/greenDAO · error · RuntimeException

Source properties do not match target properties:

Error message

Source properties do not match target properties: 

What it means

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.

Solutions

  1. Make the source and target property lists the same length, pairing columns positionally
  2. Use the simple addToMany(targetEntity, targetProperty) overload for single-column relations
  3. For composite keys, pass matching counts on both sides (e.g. 2 source PKs and 2 target FKs)
  4. Print both lists during generation setup to confirm the pairing

Example fix

// before
toMany.setSourceProperties(srcA, srcB); // 2 sources
toMany.setTargetProperties(tgtA);       // 1 target -> mismatch
// after
toMany.setTargetProperties(tgtA, tgtB); // 2 targets, paired positionally
Defensive patterns

Strategy: validation

Validate before calling

if (sourceProps.size() != targetProps.size()) throw new IllegalArgumentException("ToMany source/target property counts differ");

Type guard

function countsMatch(src, tgt) { return Array.isArray(src) && Array.isArray(tgt) && src.length === tgt.length; }

Try / catch

try { schema.generate(); } catch (RuntimeException e) { if (e.getMessage().startsWith("Source properties do not match target")) { comparePropertyLists(); } else { throw e; } }

Prevention

When it happens

Trigger: Calling setSourceProperties/setTargetProperties (or a constructor variant) on a ToMany with lists of different lengths, e.g. two source columns against one target column.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of greenrobot/greenDAO@0bbb338e17 (2026-09-08). Data as JSON: /api/errors/78e03b64540abbf9. Report an issue: GitHub.

Appendix: source

Thrown at DaoGenerator/src/org/greenrobot/greendao/generator/ToMany.java:60

    }

    public Property[] getTargetProperties() {
        return targetProperties;
    }

    void init2ndPass() {
        super.init2ndPass();
        if (sourceProperties == null) {
            List<Property> pks = sourceEntity.getPropertiesPk();
            if (pks.isEmpty()) {
                throw new RuntimeException("Source entity has no primary key, but we need it for " + this);
            }
            sourceProperties = new Property[pks.size()];
            sourceProperties = pks.toArray(sourceProperties);
        }
        int count = sourceProperties.length;
        if (count != targetProperties.length) {
            throw new RuntimeException("Source properties do not match target properties: " + this);
        }

        for (int i = 0; i < count; i++) {
            Property sourceProperty = sourceProperties[i];
            Property targetProperty = targetProperties[i];

            PropertyType sourceType = sourceProperty.getPropertyType();
            PropertyType targetType = targetProperty.getPropertyType();
            if (sourceType == null || targetType == null) {
                throw new RuntimeException("Property type uninitialized");
            }
            if (sourceType != targetType) {
                System.err.println("Warning to-one property type does not match target key type: " + this);
            }
        }
    }

    void init3rdPass() {

View on GitHub (pinned to 0bbb338e17)