Skip to content

[NAE-2400] Prevent Caching of Null Results in Process Cache#427

Merged
machacjozef merged 10 commits intorelease/7.0.0-rev10from
NAE-2400
Apr 10, 2026
Merged

[NAE-2400] Prevent Caching of Null Results in Process Cache#427
machacjozef merged 10 commits intorelease/7.0.0-rev10from
NAE-2400

Conversation

@machacjozef
Copy link
Copy Markdown
Member

@machacjozef machacjozef commented Apr 2, 2026

Description

  • Updated @Cacheable annotations in PetriNetService to avoid caching null results.

Fixes NAE-2400

Dependencies

Third party dependencies

Blocking Pull requests

<Depends on #(PR id)>/

How Has Been This Tested?

  • <Name of a test [test file](link to the test file)>

Test Configuration

<Please describe configuration for tests to run if applicable, like program parameters, host OS, VM configuration etc.>

Name Tested on
OS
Runtime
Dependency Manager
Framework version
Run parameters
Other configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes have been checked, personally or remotely, with @...
  • I have commented my code, particularly in hard-to-understand areas
  • I have resolved all conflicts with the target branch of the PR
  • I have updated and synced my code with the target branch
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes:
    • Lint test
    • Unit tests
    • Integration tests
  • I have checked my contribution with code analysis tools:
  • I have made corresponding changes to the documentation:
    • Developer documentation
    • User Guides
    • Migration Guides

Summary by CodeRabbit

  • New Features

    • Added targeted cache eviction to remove specific Petri net entries across multiple caches using id/identifier/version parameters.
    • Exposed this targeted eviction in the service API for precise cache control.
  • Bug Fixes

    • Caching updated to avoid storing null Petri net results, preventing missing-data being cached.
  • Chores

    • Bumped project parent version across modules for consistent configuration.
    • Added informational logging around Petri net caching operations.

- Updated `@Cacheable` annotations in `PetriNetService` to avoid caching null results.
@machacjozef machacjozef self-assigned this Apr 2, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 2, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 850f3ea2-1fa5-466e-bc47-a4d6e720f764

📥 Commits

Reviewing files that changed from the base of the PR and between 2843d3d and dfc012f.

📒 Files selected for processing (1)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FieldActionsCacheService.java

Walkthrough

Adds a targeted cache-eviction method evictCache(String id, String identifier, String version) to PetriNetService/IPetriNetService and tightens two @Cacheable annotations to avoid caching null returns (unless = "#result == null").

Changes

Cohort / File(s) Summary
Interface: new eviction API
application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java
Added void evictCache(String id, String identifier, String version); to expose targeted multi-cache eviction.
Service: cache behavior & eviction
application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java
Added evictCache(String id, String identifier, String version) which evicts keys across caches (petriNetById, petriNetByIdentifier, petriNetDefault, petriNetLatest, petriNetCache) using different key forms (e.g., new ObjectId(id), id, identifier, identifier+version, version). Updated @Cacheable on get(ObjectId) and getPetriNet(String) to include unless = "#result == null".
Logging: field actions cache
application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FieldActionsCacheService.java
Added informational log entries at start/end of cachePetriNetFunctions(PetriNet).
Parent POM version bumps
pom.xml, application-engine/pom.xml, nae-object-library/pom.xml, nae-spring-core-adapter/pom.xml, nae-user-ce/pom.xml, nae-user-common/pom.xml
Bumped parent/project version from 7.0.0-RC10.17.0.0-RC10.2 across root and modules; no source API changes.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller
    participant Service as PetriNetService
    participant CacheMgr as CacheManager
    participant Caches as PetriNetCaches

    Caller->>Service: evictCache(id, identifier, version)
    Service->>CacheMgr: compute target keys (ObjectId(id), id, identifier, identifier+version, version)
    CacheMgr->>Caches: evict("petriNetById", new ObjectId(id))
    CacheMgr->>Caches: evict("petriNetById", id)
    CacheMgr->>Caches: evict("petriNetByIdentifier", identifier)
    CacheMgr->>Caches: evict("petriNetByIdentifier", identifier+version)
    CacheMgr->>Caches: evict("petriNetCache", version)
    CacheMgr->>Caches: evict("petriNetDefault", identifier)
    CacheMgr->>Caches: evict("petriNetLatest", identifier)
    Caches-->>CacheMgr: confirmations
    CacheMgr-->>Service: eviction complete
    Service-->>Caller: return
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'NAE-2400 Prevent Caching of Null Results in Process Cache' directly and clearly summarizes the main change: adding cache conditions to prevent null results from being cached in the PetriNetService.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

renczesstefan
renczesstefan previously approved these changes Apr 2, 2026
@machacjozef machacjozef requested review from Kovy95, Retoocs and tuplle April 8, 2026 07:47
@machacjozef machacjozef marked this pull request as ready for review April 8, 2026 07:47
@coderabbitai coderabbitai Bot added bugfix A change that fixes a bug Extra Small labels Apr 8, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java`:
- Line 153: The `@Cacheable` unless="#result == null" is ineffective because the
two PetriNetService methods currently throw when a net is missing instead of
returning null; update the two cached methods in PetriNetService (the two
methods currently annotated with `@Cacheable`) to catch the "not found" exception
they throw (e.g., ResourceNotFoundException/NoSuchElementException used in this
service) and return null instead so the unless condition can take effect and
missing nets are not cached; ensure you only convert the missing-resource path
to return null and preserve throwing for other error cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e06acaa3-ca9a-4358-86d7-c60b722d3203

📥 Commits

Reviewing files that changed from the base of the PR and between fe97154 and 746d40f.

📒 Files selected for processing (1)
  • application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java

*/
@Override
@Cacheable(value = "petriNetCache")
@Cacheable(value = "petriNetCache", unless = "#result == null")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

unless = "#result == null" is a no-op here and does not implement the PR objective

At Line 153 and Line 304, both methods throw on not-found instead of returning null, so the unless condition is never hit and caching behavior is unchanged. This likely leaves NAE-2400 unresolved in this class.

Based on learnings: In this repository, petriNetService.get() does not return null when a net is missing; it fails via exception.

Also applies to: 304-304

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java`
at line 153, The `@Cacheable` unless="#result == null" is ineffective because the
two PetriNetService methods currently throw when a net is missing instead of
returning null; update the two cached methods in PetriNetService (the two
methods currently annotated with `@Cacheable`) to catch the "not found" exception
they throw (e.g., ResourceNotFoundException/NoSuchElementException used in this
service) and return null instead so the unless condition can take effect and
missing nets are not cached; ensure you only convert the missing-resource path
to return null and preserve throwing for other error cases.

tuplle
tuplle previously approved these changes Apr 8, 2026
Kovy95
Kovy95 previously approved these changes Apr 9, 2026
- added new function for evicting petriNet cache by several string properties
@renczesstefan renczesstefan dismissed stale reviews from Kovy95, tuplle, and themself via 3653f03 April 9, 2026 10:59
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java (1)

162-167: ⚠️ Potential issue | 🟠 Major

unless = "#result == null" is ineffective here and does not change caching behavior.

Both methods throw on not-found instead of returning null, so the unless predicate is never reached in the miss path. This is the same unresolved issue noted earlier.

#!/bin/bash
# Verify that the two methods with `unless = "#result == null"` throw on miss
# and do not return null in the not-found path.
rg -n -C3 \
  'public PetriNet get\(ObjectId petriNetId\)|public PetriNet getPetriNet\(String id\)|@Cacheable\(value = "petriNetCache", unless = "#result == null"\)|@Cacheable\(value = "petriNetById", unless = "#result == null"\)|throw new IllegalArgumentException|return null' \
  application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java

Based on learnings: In this repository, petriNetService.get() does not return null for missing nets and fails via exception.

Also applies to: 313-318

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java`
around lines 162 - 167, The `@Cacheable` annotations on
PetriNetService.get(ObjectId petriNetId) and getPetriNet(String id) include
unless = "#result == null" which is ineffective because both methods throw
IllegalArgumentException on not-found instead of returning null; fix by removing
the unless attribute from the `@Cacheable` declarations (i.e., change
`@Cacheable`(value = "petriNetCache", unless = "#result == null") and
`@Cacheable`(value = "petriNetById", unless = "#result == null") to simply
`@Cacheable`(value = "petriNetCache") / `@Cacheable`(value = "petriNetById")), or
alternatively alter the methods (get/getPetriNet) to return null on not-found if
you intend to keep the unless check—choose one consistent approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java`:
- Around line 141-148: In PetriNetService.evctCache (method evictCache) the
eviction for cacheProperties.getPetriNetByIdentifier() uses the wrong key (id +
version); change it to evict(identifier + version) so it matches the lookup key
used when populating petriNetByIdentifier and prevents stale entries; update the
call
requireNonNull(cacheManager.getCache(cacheProperties.getPetriNetByIdentifier()),
cacheProperties.getPetriNetByIdentifier()).evict(...) accordingly.

---

Duplicate comments:
In
`@application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java`:
- Around line 162-167: The `@Cacheable` annotations on
PetriNetService.get(ObjectId petriNetId) and getPetriNet(String id) include
unless = "#result == null" which is ineffective because both methods throw
IllegalArgumentException on not-found instead of returning null; fix by removing
the unless attribute from the `@Cacheable` declarations (i.e., change
`@Cacheable`(value = "petriNetCache", unless = "#result == null") and
`@Cacheable`(value = "petriNetById", unless = "#result == null") to simply
`@Cacheable`(value = "petriNetCache") / `@Cacheable`(value = "petriNetById")), or
alternatively alter the methods (get/getPetriNet) to return null on not-found if
you intend to keep the unless check—choose one consistent approach.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ac3074a9-e375-434e-a10a-938476961958

📥 Commits

Reviewing files that changed from the base of the PR and between 746d40f and 3653f03.

📒 Files selected for processing (2)
  • application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java
  • application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java

Replaced the incorrect use of 'id' with 'identifier' when evicting caches associated with PetriNet objects. This ensures consistency and proper functioning of the cache eviction process.
@coderabbitai coderabbitai Bot added the Medium label Apr 9, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java (1)

162-163: ⚠️ Potential issue | 🟠 Major

unless = "#result == null" is ineffective on these two methods.

At Line 162 and Line 313, the methods throw on not-found (Line 166 and Line 317) instead of returning null, so the unless condition is never hit. This means caching behavior is unchanged by these annotations and the intended null-result handling is not implemented here.

Based on learnings: In the netgrif/application-engine project, the petriNetService.get() method (from IPetriNetService) never returns null and handles missing nets via exception paths.

Also applies to: 313-314

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java`
around lines 162 - 163, The `@Cacheable` annotation's unless = "#result == null"
is ineffective because PetriNetService.get(...) throws when a net is missing
rather than returning null; remove the unless attribute from the `@Cacheable` on
the get(ObjectId petriNetId) method (and the other get(...) overload flagged) so
caching behavior matches reality, or alternatively change the method to return
null instead of throwing if you truly want the unless guard to apply — update
the annotations on the get methods (e.g., get(ObjectId petriNetId) and the other
get(...) overload) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java`:
- Around line 162-163: The `@Cacheable` annotation's unless = "#result == null" is
ineffective because PetriNetService.get(...) throws when a net is missing rather
than returning null; remove the unless attribute from the `@Cacheable` on the
get(ObjectId petriNetId) method (and the other get(...) overload flagged) so
caching behavior matches reality, or alternatively change the method to return
null instead of throwing if you truly want the unless guard to apply — update
the annotations on the get methods (e.g., get(ObjectId petriNetId) and the other
get(...) overload) accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c2820688-14a6-4a8a-a9de-3d771408bdb0

📥 Commits

Reviewing files that changed from the base of the PR and between 3653f03 and c3b91da.

📒 Files selected for processing (1)
  • application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java

@coderabbitai coderabbitai Bot added the breaking change Fix or feature that would cause existing functionality doesn't work as expected label Apr 9, 2026
Kovy95
Kovy95 previously approved these changes Apr 9, 2026
Retoocs
Retoocs previously approved these changes Apr 9, 2026
tuplle
tuplle previously approved these changes Apr 9, 2026
Included log statements to indicate the start and completion of caching functions for a given PetriNet. This improves traceability and aids in debugging by providing clear insights into the caching process.
@renczesstefan renczesstefan dismissed stale reviews from tuplle, Retoocs, and Kovy95 via dfc012f April 9, 2026 16:01
@machacjozef machacjozef merged commit 39a257c into release/7.0.0-rev10 Apr 10, 2026
6 of 7 checks passed
@machacjozef machacjozef deleted the NAE-2400 branch April 10, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Fix or feature that would cause existing functionality doesn't work as expected bugfix A change that fixes a bug Extra Small Medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants