Repository navigation
intent: a .print reaches a cross-model relation's own relation, and an audited document's CreatedBy / UpdatedBy (#7752, #8609) - #8614
Merged
Conversation
…cument.Customer.City.Name}} (#7752) A record of another model is copied onto the print payload reflectively (#6422), so its own to-one relations arrived as bare keys and {{document.Customer.City.Name}} rendered empty. The owner now declares its references and the consumer follows them at runtime: the generated entity carries @reference(repository, label) on every to-one foreign-key field, and the feeder asks the new SDK PrintRecords.expandReferences to replace each such key with the referenced record's fields and __label. Nothing of the owner's relation graph is named in the consumer's generated source. One hop only, for a cross-model relation of the document or of a line item; one load per distinct (repository, key) per payload, shared by the header relations and every item row. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…y / CreatedAt / UpdatedBy / UpdatedAt (#8609) The audit columns are injected by the EDM generator, not authored, so the print feeder - built from the authored fields - never put them and {{document.CreatedBy}} rendered empty. An audited document master now gets the four columns on `document`, under the names the generated entity declares, the timestamps as ISO instants. Line items, relation nodes and non-audited documents are unchanged. No CreatedByName: the platform keeps no display name for a user. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
| public static class CountryRepository { | ||
| static int loads; | ||
|
|
||
| public Object findById(Object id) { |
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.
Two gaps in the payload a generated
<Entity>PrintFeederhands a.print, both in the same generator code. One commit each.#7752 - a cross-model relation's own relation was unreachable
Cause. A record of another model is copied onto the payload reflectively (
copyRecordFields, #6422), so its own to-one relations arrive as bare keys:document.Customer.Citywas1, and{{document.Customer.City.Name}}rendered empty.Design: the owner declares its references, the consumer follows them at runtime.
Entity.java.template(dao-java) puts a new SDK annotation on every to-one foreign-key field of a generated entity:@org.eclipse.dirigible.sdk.db.Reference(repository = "gen.countries.data.settings.CityRepository", label = "Name"). The store does not read it; persistence is unchanged.org.eclipse.dirigible.sdk.print.PrintRecords.expandReferences(record, map, loadedReferences)right aftercopyRecordFields. It reads the annotations off the loaded record's class, loads each referenced record through its repository (so the language overlay applies) and replaces the key with that record's fields plus__label.PrintFeederSupportonly flags the node (expandReferences); it emits no node for the owner's relations and names none of them.Why not the two simpler routes. Reading the owner's relation graph from its
.modelat generation time and emitting a node per relation compilescustomer.Cityandgen.countries...CityRepositoryinto the consumer - the #6422 failure again: the owner drops or retargets a relation, the never-regenerated consumer stops compiling, and the all-or-nothing client-Java batch takes every module down. Baking the same names as strings and loading reflectively compiles forever but is still a snapshot of another model's schema in the consumer'sgen/. With the annotation the relation graph is written exactly once, by its owner, in code that is regenerated with it.Bounds and cost.
PrintRecordsnever recurses).findByIdper distinct (repository, key) per payload. The cache is shared by the header relations and all item rows, and remembers misses, so there is no load per row. A print pays about one extra read per set to-one relation of each cross-model record it carries (a customer with City, Country, Currency, Kind set: four reads).What changes for existing modules.
PrintRecordscall and the cache map.{{document.Customer.City}}now prints the city's label where it printed the integer key.@Reference, so its records keep their keys, with no error. A reference whose repository class is absent or whose record is gone also keeps its key (logged at WARN).#8609 - an
audit: truedocument carried no audit columnsCause. The four audit columns are injected by
EdmIntentGenerator.auditProperties, they are not authored fields, and the feeder'srootScalarsare built from the authored fields only.Change. For an audited document master
PrintFeederSupportappendsCreatedAt,CreatedBy,UpdatedAt,UpdatedBy(the names the generated entity declares) to the root scalars; the two timestamps print as ISO instants. Root only - line items, relation nodes and non-audited documents are unchanged.UpdatedBy/UpdatedAtare absent from the JSON until the record is first updated (null keys are not serialised).No
CreatedByName/UpdatedByName. The platform has no display name to resolve: the tenantUseris id, username, password and roles, andCreatedByholds whatUserFacade.getName()returned (the username, or the identity provider's principal). Left out rather than faked.Verification
Run locally on this branch:
mvn install -pl components/api/api-modules-java,components/template/template-application-dao-java,components/template/template-application-events-java,components/ide/ide-template,components/engine/engine-intent- api-modules-java 130 tests, ide-template 359, engine-intent 2124, 0 failures. New:PrintRecordsTest(6), three tests inPrintFeederSupportTest.IntentCrossModelFieldRetirementIT(extended) generates an owner and a consumer project, publishes both and reads the feeder over HTTP:document.Invoice.City.Nameanddocument.Invoice.City.__labelareSofiafrom a consumer whose source names neitherCitynor its repository, anddocument.CreatedByisadminwithdocument.CreatedAtset.mvn -P integration-tests -pl tests/tests-integrations verify -Dit.test=... -Dit.groups= -Dit.excludedGroups=forIntentEngineIT(83),ModelGenerationIT(1),IntentClickRoleGateIT(2),IntentExtraRolesIT(2),IntentCrossModuleCollisionIT(1),IntentEmissionCoverageIT(1) - all green.IntentEmissionCoverageITtimed out once inassertBpmEventsRuntime(the 180 s wait for a BPM expiry timer,State == EXPIRED) while running in the same batch, and passed when re-run with this branch unchanged; noted here in case CI shows the same.-P release -Dgpg.skip=true -DskipTests) of the five changed modules.generate --checkon the threesample-intent-*projects with the rebuilt application jar: no drift (none of them commits an entity with a relation or a print feeder), so there is no regenerated sample output in this PR.mvn formatter:validateon the reactor with the formatter caches wiped.Not run locally: the PostgreSQL leg and the full integration suite (CI).
Fixes #7752
Fixes #8609
🤖 Generated with Claude Code