Skip to content

Add @OrderBy to JpaRollout.rolloutGroups to fix rollout on PostgreSQL#3009

Open
clayly wants to merge 1 commit intoeclipse-hawkbit:masterfrom
clayly:fix/rollout-group-ordering
Open

Add @OrderBy to JpaRollout.rolloutGroups to fix rollout on PostgreSQL#3009
clayly wants to merge 1 commit intoeclipse-hawkbit:masterfrom
clayly:fix/rollout-group-ordering

Conversation

@clayly
Copy link
Copy Markdown

@clayly clayly commented Apr 9, 2026

Summary

The rolloutGroups @OneToMany collection in JpaRollout lacks an @OrderBy annotation, leaving iteration order undefined. Multiple code paths depend on this list being ordered by creation time (ascending ID):

  • JpaRolloutExecutor.fillDynamicRolloutGroupsWithTargets() uses .get(size()-1) to find the latest dynamic group
  • JpaRolloutExecutor.handleRunningRollout() uses .get(size()-1) to identify the last group
  • RolloutHelper.toPercentFromTheRest() iterates groups in sequence to calculate target percentages (comment in code: "assume that the groups are served orderly")
  • JpaRolloutManagement.resumeRollout() takes the last element of a filtered list as the "last started group"

On H2 rows happen to be returned in insertion order, but PostgreSQL and compatible databases do not guarantee any ordering without explicit ORDER BY. This causes:

  • Spurious dynamic group creation (expected 2 groups, got 3)
  • Wrong action counts per group (expected 3 running, got 5-7)
  • Group status transitions stuck in SCHEDULED instead of RUNNING

Changes

Added @OrderBy("id ASC") to JpaRollout.rolloutGroups. This makes the JPA provider include ORDER BY when loading the collection, fulfilling the ordering assumption the code already relies on.

Test plan

  • RolloutManagementFlowTest (10 tests) passes on H2 (default)
  • RolloutManagementFlowTest (10 tests) passes on PostgreSQL 15
  • RolloutManagementFlowTest (10 tests) passes on YugabyteDB (PostgreSQL 15.12-YB-2025.2.2.2-b0)

The rolloutGroups @onetomany collection lacked an @orderby annotation,
leaving the iteration order of rollout groups undefined. Multiple code
paths depend on this list being ordered by creation time (ID):

- JpaRolloutExecutor uses .get(size()-1) to find the latest group
- RolloutHelper.toPercentFromTheRest iterates groups in sequence to
  calculate target percentages (comment: "assume groups served orderly")
- JpaRolloutManagement.resumeRollout gets the last started group by
  position

On H2 (in-memory) rows happen to be returned in insertion order, but
PostgreSQL and compatible databases (YugabyteDB, CockroachDB) do not
guarantee any ordering without explicit ORDER BY. This caused rollout
group status transitions, dynamic group creation, and target assignment
to malfunction on PostgreSQL.

Adding @orderby("id ASC") makes the JPA provider include ORDER BY when
loading the collection, fulfilling the ordering assumption the code
already relies on.

Verified passing on H2, PostgreSQL 15, and YugabyteDB.
@hawkbit-bot
Copy link
Copy Markdown

Thanks @clayly for taking the time to contribute to hawkBit! We really appreciate this. Make yourself comfortable while I'm looking for a committer to help you with your contribution.
Please make sure you read the contribution guide and signed the Eclipse Contributor Agreement (ECA).

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.

2 participants