Skip to content

AAE-52887 Fix(audit): omit null precedence in timestamp DESC queries - #2850

Merged
eromano merged 5 commits into
developfrom
fix/audit-v2-sort-null-precedence
Nov 7, 2026
Merged

eromano merged 5 commits into
developfrom
fix/audit-v2-sort-null-precedence

Conversation

Copilot AI commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Production audit queries render ORDER BY timestamp DESC NULLS LAST, e.g.:

select ... from audit_event aee1_0
where aee1_0.timestamp between $1 and $2
order by aee1_0.timestamp desc nulls last
offset $3 rows fetch first $4 rows only;

The shared SessionFactory sets hibernate.order_by.default_null_ordering=last globally. A Spring Sort with NATIVE null handling (e.g. Sort.by(DESC, "timestamp")) inherits that default, so Hibernate appends NULLS LAST to DESC.

The remaining timestamp index is audit_event_timestamp_idx (btree, ascending). PostgreSQL can scan it backward for plain DESC (equivalent to DESC NULLS FIRST), but not for DESC NULLS LAST, which forces a full sort. idx_audit_event_timestamp_desc_nulls_last was dropped by changelog 23.

Fix

Tests

  • New AuditEventsTimestampOrderingSqlIT: renders SQL with PostgreSQLDialect + default_null_ordering=last and captures statements via a Hibernate StatementInspector. Asserts the v2 search and export BETWEEN queries contain order by ...timestamp desc and no nulls.
  • AuditEventsAdminServiceTest: export requests timestamp DESC NULLS_FIRST.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added the bug Something isn't working label Nov 7, 2026
@eromano eromano changed the title fix(audit): omit null precedence in v2 default sort AAE-52887 Fix(audit): omit null precedence in v2 default sort Nov 7, 2026
@eromano
eromano marked this pull request as ready for review November 7, 2026 08:15
@github-actions

github-actions Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

playswag — API Coverage Report

Dimension Covered Total %
Endpoints 135 140 🟢 96.4%
Status Codes 212 937 🔴 22.6%
Parameters 136 688 🔴 19.8%
Body Properties 127 668 🔴 19.0%
Response Properties 1210 3549 🔴 34.1%

Coverage by Tag

Tag Endpoints Status Codes Parameters Body Props Resp Props
task-controller-impl 🟢 100.0% 🔴 17.7% 🟡 56.3% 🟡 60.6% 🔴 40.4%
task-variable-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟢 80.0% 🔴 4.8%
process-instance-controller-impl 🟢 100.0% 🔴 17.0% 🟡 57.1% 🔴 45.2% 🔴 42.0%
process-instance-variable-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟡 50.0% 🔴 6.7%
task-admin-controller-impl 🟢 100.0% 🔴 12.5% 🟡 62.5% 🟡 57.1% 🔴 31.3%
task-variable-admin-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟢 80.0% 🔴 4.8%
process-instance-admin-controller-impl 🟢 100.0% 🔴 13.6% 🟡 57.1% 🔴 39.1% 🔴 40.2%
process-instance-variable-admin-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟡 50.0% 🔴 4.8%
candidate-user-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟡 75.0% 🔴 4.8%
candidate-group-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟡 75.0% 🔴 4.8%
candidate-user-admin-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟡 75.0% 🔴 4.8%
candidate-group-admin-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟡 75.0% 🔴 4.8%
service-task-admin-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟢 100.0% 🔴 0.0%
home-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟢 100.0% 🔴 10.0%
process-instance-tasks-controller-impl 🟢 100.0% 🔴 12.5% 🔴 25.0% 🟢 100.0% 🔴 33.3%
process-definition-controller-impl 🟢 100.0% 🔴 12.5% 🟡 50.0% 🟢 100.0% 🔴 18.6%
process-definition-meta-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟢 100.0% 🔴 0.0%
connector-definition-controller-impl 🟢 100.0% 🔴 12.5% 🟢 100.0% 🟢 100.0% 🔴 16.0%
process-definition-admin-controller-impl 🟢 100.0% 🔴 12.5% 🔴 0.0% 🟢 100.0% 🔴 33.3%
task-controller 🟢 100.0% 🟡 60.0% 🔴 25.0% 🔴 6.8% 🔴 45.8%
process-instance-controller 🟢 100.0% 🟡 60.0% 🔴 10.4% 🔴 5.6% 🟡 54.1%
count-controller 🔴 0.0% 🔴 0.0% 🟢 100.0% 🔴 0.0% 🔴 0.0%
task-admin-controller 🟢 100.0% 🟡 62.9% 🔴 13.7% 🔴 8.8% 🔴 44.9%
task-delete-controller 🟢 100.0% 🔴 20.0% 🔴 0.0% 🟢 100.0% 🔴 16.7%
process-instance-admin-controller 🟢 100.0% 🔴 45.0% 🔴 8.2% 🔴 2.8% 🔴 47.6%
process-instance-delete-controller 🟢 100.0% 🔴 20.0% 🔴 0.0% 🟢 100.0% 🔴 16.7%
count-admin-controller 🔴 0.0% 🔴 0.0% 🟢 100.0% 🔴 0.0% 🔴 0.0%
task-variable-controller 🟢 100.0% 🔴 20.0% 🔴 14.3% 🟢 100.0% 🟡 50.0%
process-instance-variable-controller 🟢 100.0% 🔴 20.0% 🔴 11.1% 🟢 100.0% 🟡 50.0%
process-instance-tasks-controller 🟢 100.0% 🔴 20.0% 🔴 20.0% 🟢 100.0% 🟡 50.0%
process-instance-diagram-controller 🟢 100.0% 🔴 20.0% 🟢 100.0% 🟢 100.0% 🔴 0.0%
process-definition-controller 🟢 100.0% 🔴 20.0% 🔴 0.0% 🟢 100.0% 🟡 50.0%
process-model-controller 🟢 100.0% 🔴 20.0% 🟢 100.0% 🟢 100.0% 🔴 0.0%
application-controller 🟢 100.0% 🔴 20.0% 🔴 0.0% 🟢 100.0% 🟡 50.0%
task-variable-admin-controller 🟢 100.0% 🟡 60.0% 🔴 14.3% 🟢 100.0% 🟡 50.0%
service-task-admin-controller 🟢 100.0% 🔴 20.0% 🔴 10.0% 🟢 100.0% 🟡 57.1%
service-task-integration-context-admin-controller 🟢 100.0% 🔴 20.0% 🔴 40.0% 🟢 100.0% 🔴 49.2%
process-instance-variable-admin-controller 🟢 100.0% 🔴 40.0% 🔴 11.1% 🟢 100.0% 🟡 50.0%
process-instance-tasks-admin-controller 🟢 100.0% 🔴 20.0% 🔴 25.0% 🟢 100.0% 🟡 50.0%
process-instance-service-tasks-admin-controller 🟢 100.0% 🔴 20.0% 🔴 10.0% 🟢 100.0% 🟡 50.0%
process-instance-sequence-flows-admin-controller 🟢 100.0% 🔴 40.0% 🔴 5.3% 🟢 100.0% 🟡 50.0%
process-instance-diagram-admin-controller 🟢 100.0% 🔴 40.0% 🟢 100.0% 🟢 100.0% 🔴 0.0%
process-instance-bpmn-activities-admin-controller 🟢 100.0% 🔴 20.0% 🔴 25.0% 🟢 100.0% 🟡 50.0%
process-definition-admin-controller 🟢 100.0% 🔴 20.0% 🔴 0.0% 🟢 100.0% 🟡 50.0%
process-model-admin-controller 🟢 100.0% 🔴 20.0% 🟢 100.0% 🟢 100.0% 🔴 0.0%
integration-context-admin-controller 🟢 100.0% 🟡 60.0% 🟢 100.0% 🟢 100.0% 🟡 55.3%
application-admin-controller 🟢 100.0% 🟡 60.0% 🔴 0.0% 🟢 100.0% 🟡 50.0%
audit-events-controller-v-2-impl 🔴 0.0% 🔴 0.0% 🔴 0.0% 🟢 100.0% 🔴 0.0%
audit-events-controller-impl 🟢 100.0% 🟡 50.0% 🟢 80.0% 🟢 100.0% 🟡 67.3%
audit-events-admin-controller-v-2-impl 🔴 0.0% 🔴 0.0% 🔴 0.0% 🟢 100.0% 🔴 0.0%
audit-events-admin-controller-impl 🟢 100.0% 🟡 70.0% 🟢 100.0% 🟢 100.0% 🔴 44.4%
audit-events-delete-controller 🟢 100.0% 🔴 20.0% 🟢 100.0% 🟢 100.0% 🔴 0.0%

View workflow run

eromano and others added 2 commits November 7, 2026 09:04
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

🐢 Slow Tests Report

🧪 Unit Tests

The following 20 unit test(s) took more than 5 seconds:

Time # Class Test
22.66s 1 org.activiti.services.connectors.IntegrationRequestSenderTest shouldSendExpirationHeaders
20.54s 2 org.activiti.services.connectors.behavior.MQServiceTaskBehaviorTest executeShouldDelegateToDefaultBehaviourWhenBeanIsAvailable
14.41s 3 org.activiti.services.connectors.channel.AggregateIntegrationErrorReceivedEventCmdTest should_aggregateIntegrationErrorReceivedEvent_when_auditEventAreEnabled
13.79s 4 org.activiti.services.connectors.recovery.OrphanedIntegrationRecoverySchedulerTest should_continueRecoveringRemainingContexts_when_oneRecoveryThrows
10.28s 5 org.activiti.services.connectors.IntegrationRequestSenderTest shouldSendExpirationHeaders
9.84s 6 org.activiti.cloud.alfresco.argument.resolver.AlfrescoPageArgumentMethodResolverTest resolveArgumentShouldReturnAPageableBasedOnParsedSkipCountAndMaxItems
9.69s 7 org.activiti.cloud.services.events.services.IncidentServiceTest shouldCreateAndSendExecutionContextIncidentEvent
8.97s 8 org.activiti.services.connectors.behavior.MQServiceTaskBehaviorTest executeShouldDelegateToDefaultBehaviourWhenBeanIsAvailable
8.71s 9 org.activiti.cloud.services.rest.assemblers.ProcessDefinitionMetaRepresentationModelAssemblerTest toResourceShouldReturnResourceWithSelfLinkContainingResourceId
8.70s 10 org.activiti.cloud.services.rest.assemblers.ProcessDefinitionRepresentationModelAssemblerTest toResourceShouldReturnResourceWithSelfLinkContainingResourceId
8.69s 11 org.activiti.cloud.services.rest.assemblers.ExtendedCloudProcessDefinitionRepresentationModelAssemblerTest toResourceShouldReturnResourceWithSelfLinkContainingResourceId
8.63s 12 org.activiti.cloud.common.messaging.config.ActivitiMessagingEnvironmentPostProcessorTest should_setDefaultBinderToAwsAndDisableRabbitHealthCheck_when_brokerIsAws
8.12s 13 org.activiti.cloud.services.notifications.qraphql.ws.security.ConnectionContextWebSocketInterceptorTest should_fallBackToNoGroups_when_theGroupsProviderThrows
7.89s 14 org.activiti.cloud.services.events.converter.ProcessAuditServiceInfoAppenderTest should_setAndGetActor_when_identityLinkTypeIsActor
7.34s 15 org.activiti.cloud.common.messaging.config.ConnectorGracefulShutdownLifecycleTest shouldBeRunningAfterStart
6.98s 16 org.activiti.cloud.common.messaging.config.ErrorHandlerDefinitionMessageRecovererTest shouldFindCauseAccurately(String, Throwable, Class, Optional)[1]
6.90s 17 org.activiti.cloud.services.events.converter.ToCloudProcessRuntimeErrorEventsConverterTest shouldConvertBPMNErrorReceivedEventToCloudBPMNErrorReceivedEvent
6.85s 18 org.activiti.cloud.services.events.converter.TaskAuditServiceInfoAppenderTest should_setAndGetActor_when_userHasNameSet
6.68s 19 org.activiti.cloud.common.messaging.config.ConnectorOutputBindingEnvironmentPostProcessorTest should_appendToExistingOutputBindings_withoutDuplicating
6.47s 20 org.activiti.cloud.api.process.model.impl.events.IntegrationRequestImplTest copyWithLightweightContext_should_copyAllRoutingMetadata

🏋️ Slowest Unit Test Classes (aggregated)

The following 2 class(es) took more than 30 seconds in total:

Total Time # All Tests Time > 5s Tests > 5s Class
33.01s 1 4 32.94s 2 org.activiti.services.connectors.IntegrationRequestSenderTest
32.38s 2 12 29.52s 2 org.activiti.services.connectors.behavior.MQServiceTaskBehaviorTest

🔗 Integration Tests

The following 20 integration test(s) took more than 5 seconds:

Time # Class Test
111.06s 1 org.activiti.cloud.starter.tests.recovery.OrphanedIntegrationRecoveryIT should_taskTransitionToErrorState_when_applicationIsKilledDuringServiceTaskExecution(boolean)[2]
50.07s 2 org.activiti.cloud.starter.tests.recovery.OrphanedIntegrationRecoveryIT should_taskTransitionToErrorState_when_applicationIsKilledDuringServiceTaskExecution(boolean)[1]
21.60s 3 org.activiti.cloud.starter.tests.runtime.JobExecutorIT testTimerJobsFailRetry
21.57s 4 org.activiti.cloud.starter.tests.runtime.JobExecutorIT testTimerJobsFailRetry
19.27s 5 org.activiti.cloud.starter.messages.test.redis.RedisMessageStoreIT shouldProcessMessageEventsConcurrentlyInReversedOrder
15.96s 6 org.activiti.cloud.starter.messages.test.hazelcast.HazelcastMessageStoreIT shouldProcessMessageEventsConcurrentlyInReversedOrder
15.14s 7 org.activiti.cloud.common.messaging.config.test.FunctionRouterBindingConfigurationIT messageTimeoutException
10.04s 8 org.activiti.cloud.starter.tests.recovery.OrphanedIntegrationRecoveryIT should_runRecoveryOnlyOnce_when_twoInstancesRunConcurrently
10.01s 9 org.activiti.cloud.common.messaging.config.test.FunctionRouterBindingConfigurationIT functionExecutorShouldAwaitTerminatingTasksOnDestroy
10.01s 10 org.activiti.cloud.examples.connectors.HeadersConnectorIT headersConnectorShouldNotSendIntegrationResult
9.47s 11 org.activiti.cloud.services.identity.keycloak.KeycloakClientIT should_get101Users_by_Role
8.84s 12 org.activiti.cloud.starter.messages.test.hazelcast.HazelcastMessageStoreIT shouldProcessMessageEventsConcurrently
7.54s 13 org.activiti.cloud.common.messaging.config.test.FunctionRouterBindingConfigurationIT aggregateMessageDeliveryException
7.28s 14 org.activiti.cloud.common.messaging.config.test.FunctionRouterBindingConfigurationIT testFunctionBindings
7.26s 15 org.activiti.cloud.common.messaging.config.test.FunctionRouterBindingConfigurationIT testConsumerBindings
6.07s 16 org.activiti.cloud.starter.messages.test.redis.RedisMessageStoreIT shouldProcessMessageEventsConcurrently
5.92s 17 org.activiti.cloud.notifications.graphql.starter.ActivitiGraphQLWsNativeStarterIT testGraphqlWsSubprotocolConnectionInitXAuthorizationSupported
5.83s 18 org.activiti.cloud.notifications.graphql.starter.ActivitiGraphQLWsNativeStarterIT testGraphqlWsSubprotocolConnectionInitXAuthorizationSupported
5.35s 19 org.activiti.cloud.common.swagger.apidocs.SpringdocApiDocsIT should_generateSpringdocApiDocs
5.23s 20 org.activiti.cloud.starter.messages.test.hazelcast.HazelcastMessageStoreIT testSentMessagesWithBufferInDifferentOrder

🏋️ Slowest Integration Test Classes (aggregated)

The following 7 class(es) took more than 30 seconds in total:

Total Time # All Tests Time > 5s Tests > 5s Class
171.18s 1 3 171.18s 3 org.activiti.cloud.starter.tests.recovery.OrphanedIntegrationRecoveryIT
56.06s 2 26 43.17s 2 org.activiti.cloud.starter.tests.runtime.JobExecutorIT
48.52s 3 34 47.22s 5 org.activiti.cloud.common.messaging.config.test.FunctionRouterBindingConfigurationIT
32.20s 4 17 30.04s 3 org.activiti.cloud.starter.messages.test.hazelcast.HazelcastMessageStoreIT
31.68s 5 33 24.85s 4 org.activiti.cloud.services.identity.keycloak.KeycloakClientIT
31.14s 6 17 25.34s 2 org.activiti.cloud.starter.messages.test.redis.RedisMessageStoreIT
30.64s 7 32 22.14s 4 org.activiti.cloud.notifications.graphql.starter.ActivitiGraphQLWsNativeStarterIT

📊 Full Slow Test Report

eromano and others added 2 commits November 7, 2026 16:08
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use timestamp DESC NULLS FIRST for the paged audit export so Hibernate
renders plain ORDER BY timestamp DESC on PostgreSQL even with the global
default_null_ordering=last. Move SQL assertions into a dedicated IT that
covers both v2 search and export queries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eromano eromano changed the title AAE-52887 Fix(audit): omit null precedence in v2 default sort AAE-52887 Fix(audit): omit null precedence in timestamp DESC queries Nov 7, 2026
@sonarqubecloud

sonarqubecloud Bot commented Nov 7, 2026

Copy link
Copy Markdown

@eromano
eromano merged commit d01515c into develop Nov 7, 2026
41 checks passed
@eromano
eromano deleted the fix/audit-v2-sort-null-precedence branch November 7, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants