fix: mappings skipped attributes inherited from a parent entity (#703) - #82
Merged
Conversation
…ixlabs#703) Mendix inheritance is multi-table: a child adds attributes to its parent's, and all the parent's are members of the child. A mapping element bound to one must reference the entity that DECLARES it. The builder prefixed the entity being mapped, unconditionally: attr := def.Attribute if parentEntity != "" && !strings.Contains(attr, ".") { attr = parentEntity + "." + attr // always the CHILD } so every inherited field produced a reference to an attribute that entity does not have. Studio Pro shows the field unmapped — the reported symptom — and mx check reports CE1613 "The selected attribute ... no longer exists". A second, quieter defect sat next to it: resolveAttributeType scanned only the entity's own attributes and fell through to a "String" default, so an inherited Boolean or DateTime element carried the wrong DataType even once the reference was correct. That function also matched entities by name across every domain model, ignoring the module, so a same-named entity elsewhere could win; it now resolves the module by name. Both the import and export builders carried the same two lines, and both are fixed. They route through the generalization walk added for mendixlabs#758, generalised here into ResolveMemberRef (declaring-entity reference) and ResolveMemberType (type from up the chain), each falling back to the previous behaviour when the member cannot be resolved. EntityMembersFor takes the backend directly so the mapping builders, which hold no ExecContext, can use it. This closes the mapping half of the mendixlabs#765 umbrella; the same declaring-entity rule governs entity access rules (mendixlabs#758) and the change-object writer (mendixlabs#451). Verified end-to-end on a real 11.12.2 project with an entity extending another, mapping one own and two inherited attributes in both directions: before: Map703.Contract.DocName StringType -> CE1613 Map703.Contract.Confidential StringType -> CE1613 after: Map703.DocumentBase.DocName StringType Map703.DocumentBase.Confidential BooleanType mx check -> 0 errors Both halves mutation-checked, including a test at the resolveAttributeType call site rather than only on the resolver — reverting the call site alone left the resolver's own test green. Docs: inheritance was unmentioned in every mapping doc, so the syntax topic, the json-structures-and-mappings skill and docs-site create-import-mapping now cover it. Refs mendixlabs#703, mendixlabs#765
The doctype example granted read on SecTest.Customer (Notes), but the entity only declares Name, Email and IsActive. Before mendixlabs#758 an unmatched member name was dropped in silence, so the grant did nothing and the script still passed; with that silence replaced by an error the example fails, and the integration tier caught it. The example is what is wrong: its own comment says "adding Notes access preserves existing Name and Email", so it always meant to demonstrate an additive grant on a third attribute. Declaring Notes makes it do that. Fixes the build-and-test failure on main introduced by #81.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes mendixlabs/mxcli#703 — the mapping half of the #765 umbrella, following mendixlabs#758 (access rules).
Problem
Mendix inheritance is multi-table: a child adds attributes to its parent's, and all the parent's are members of the child. A mapping element bound to one must reference the entity that declares it. The builder prefixed the entity being mapped, unconditionally:
So every inherited field produced a reference to an attribute that entity doesn't have. Studio Pro shows the field unmapped — the reported symptom — and
mx checkreports CE1613 "The selected attribute … no longer exists".A second, quieter defect sat next to it.
resolveAttributeTypescanned only the entity's own attributes and fell through to a"String"default, so an inheritedBooleanorDateTimeelement carried the wrongDataTypeeven once the reference was correct. Worth noting because fixing only the reference would have looked like a complete fix while silently mistyping every inherited non-String field.That function also matched entities by name across every domain model, ignoring the module — a same-named entity elsewhere could win. It now resolves the module by name.
Approach
Both the import and export builders carried the same two lines; both are fixed. They route through the generalization walk added for mendixlabs#758, generalised here into:
ResolveMemberRef— the declaring-entity reference for a memberResolveMemberType— the member's type, found up the chainEach falls back to the previous behaviour when the member can't be resolved, so an unresolvable name behaves exactly as before rather than changing shape.
EntityMembersFornow takes the backend directly, since the mapping builders hold noExecContext.Verification
End-to-end on a real 11.12.2 project — one own and two inherited attributes, mapped in both directions:
Map703.Contract.DocName→ CE1613StringTypeMap703.Contract.Confidential→ CE1613StringType❌Map703.DocumentBase.DocNameStringTypeMap703.DocumentBase.ConfidentialBooleanType✅mx check→ 0 errors (was 2 × CE1613). Full./...suite green.Both halves mutation-checked — including one detail worth flagging for review: my first mutation of the type fix passed, because the unit test exercised
ResolveMemberTypedirectly while the mutation disabled its call site inresolveAttributeType. I added a test at the call site, which does fail under that mutation. A resolver test proves the resolver, not that anything uses it.Repro script:
mdl-examples/bug-tests/703-mapping-inherited-attributes.mdl(covers import and export).Documentation
Inheritance was unmentioned in every mapping doc, so this adds it to
mxcli syntax import-mapping, thejson-structures-and-mappingsskill, and docs-sitecreate-import-mapping.md.Generalisable lesson (recorded in the symptom table)
When one rule has several call sites, a fix at one proves nothing about the others — grep for the pattern (
range entity.Attributes,parentEntity + ".") rather than the reported symptom. This is the third site of the same declaring-entity rule; mendixlabs#451's was already fixed independently in the microflow path, which is exactly why mendixlabs#765 was filed as an umbrella.With this, mendixlabs#765's three covered issues are all closed: mendixlabs#758 (access rules), mendixlabs#703 (mappings), mendixlabs#451 (change-object writer).
Generated by Claude Code