Skip to content

feat(node-server): the incremental migrations of incrementalChangelog, like the incremental changelogs of Liquibase - #1570

Closed
mshima wants to merge 3 commits into
jhipster:mainfrom
mshima:incremental-changelog
Closed

mshima wants to merge 3 commits into
jhipster:mainfrom
mshima:incremental-changelog

Conversation

@mshima

@mshima mshima commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

With incrementalChangelog, the server now migrates the changes of the entities like the incremental Liquibase changelogs of JHipster Spring Boot. Before, a regeneration rewrote the AddedEntity migration of a changed entity. A database that had run it did not run it again, so a new field or relationship was missing at runtime: dev and prod run migrationsRun without synchronize.

Depends on jhipster/generator-jhipster#35746: generator-jhipster is pinned to its commit ed4a0804, which adds the changelogs of the entities (generator-jhipster/generators/base-entity-changes/generators/changelogs/support). The pin has to move to a jhipster/generator-jhipster commit once that PR is merged.

The migrations of an entity are the ones of its changelogs, which JHipster records as objects in the .yo-rc.json, one for each change of an entity, compared to the entity of its last changelog:

  • a creation gives AddedEntity<Entity> and, when the entity has join columns or join tables, AddedEntityConstraints<Entity>, like the added_entity changelogs;
  • an update gives:
    • UpdatedEntity<Entity>, at the date of the changelog plus 6000000000000, so it runs after every constraints migration, like the incremental section of master.xml. It adds the columns of the added fields and drops the ones of the removed fields, like updated_entity;
    • UpdatedEntityConstraints<Entity>, 1 ms later. It drops the join columns, their foreign keys and the join tables of the removed relationships, then adds the ones of the added relationships, like updated_entity_constraints.

A generation writes the migrations of its own changelogs and keeps the others, registering every one in orm.config.ts without reading the folder of the migrations. A generation of the project configuration alone, without src/migrations, therefore gives the same migrations as the cli. In a project without changelogs, JHipster first records the creations of the entities from their .jhipster files on the disk; those count as former changelogs, their migrations already written.

What an update migrates:

  • Removed fields and relationships: prepared the way JHipster prepares the ones of the entities: the column names (the server prepareField), the blob types of the entity files, the join table names (getJoinTableName), and the owner side.
  • A relationship changed in its type, its entity or its side: dropped and added again.
  • A relationship changed only in its onDelete or onUpdate: left alone, since the foreign keys of the server don't declare them.
  • A field changed in place (its type, its validations): not migrated, like Liquibase.

migrations/support/schema.ts gets addColumns and dropColumns, which skip the columns the database already has or no longer has, like createTable. The unique columns of createTable are shared with addColumns. Without incrementalChangelog, a generation is unchanged except for the README of the server, which now describes both modes.

Verified:

  • The blueprint specs:
    • A project with changelogs and no folder of migrations, regenerated with incrementalChangelog: fields added and removed, a blob removed, relationships added and removed, the other side of a removed relationship, a new entity. The changelogs recorded and the dates of the migrations are checked.
    • A project without changelogs, its former entity files on the disk.
    • The support functions.
  • A generated application with a dev database (better-sqlite3), regenerated with the blueprint CLI:
    • v1: Order with fields, a blob, two many-to-one and a many-to-many relationship. Its regeneration only records the creations, rewriting no migration; its migrations run, with rows inserted.
    • v2: a field added, two fields removed (one a blob), a many-to-one and the many-to-many removed, a one-to-one added, a new entity Product with a many-to-many to Order.
    • The new migrations ran, the rows were kept, and typeorm:schema:log reports the schema up to date.
    • Typecheck passes. A regeneration without a change leaves the project unchanged.
    • A regeneration of the configuration of the project alone, without src/migrations, gives the same migrations.
  • The CI samples (generate_samples auto, base main): only the README of the server and migrations/support/schema.ts change, nothing in the MongoDB ones.

🤖 Generated with Claude Code

@mshima
mshima force-pushed the incremental-changelog branch from 264540c to ad9e2c9 Compare October 25, 2026 18:10
mshima and others added 3 commits October 25, 2026 15:56
…, like the incremental changelogs of Liquibase

With incrementalChangelog, the migrations of the entities are the ones of their changelogs JHipster records in the
objects of the .yo-rc.json (getEntityChangelogs, generator-jhipster at 6a856064 of jhipster/generator-jhipster#35746).
A creation gives AddedEntity and AddedEntityConstraints, kept once written. An update gives UpdatedEntity at the date of
its changelog plus 6000000000000, after the constraints of every entity, adding the columns of the added fields and
dropping the ones of the removed fields, then UpdatedEntityConstraints 1 ms after, adding and dropping the join columns,
their foreign keys and the join tables of the relationships. A generation writes the migrations of its own changelogs
and registers every one in orm.config.ts, without reading the folder of the migrations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nerator-jhipster at e3655959

The changelogs of this generation are the ones isNewEntityChangelog of JHipster gives, the creations of the entities a
project without changelogs already has left out, and a creation is dated by the changelogDate of its entity: the
mirrors of the blueprint (formerChangelogs, createdChangelogDate) are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…only, generator-jhipster at ed4a0804

getEntityChangelogs of JHipster records the changelogs whatever incrementalChangelog: the blueprint asks for them with
incrementalChangelog only, so a generation without it records no changelog in the .yo-rc.json. The changelogs custom
object, which no task of the blueprint used, is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mshima
mshima force-pushed the incremental-changelog branch from aba547f to c61c075 Compare October 25, 2026 18:57
@mshima mshima closed this Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant