Skip to content

KB-212 – Accounting Engine Architecture

Knowledge Base ID: KB-212
Chapter: 16 - CacheMgt & Global Cache Administration
Project: BLACK ERP
Version: 1.6
Status: Draft
Last Updated: 2026-06-27
Applies To: ADempiere 3.9.4


Purpose

This chapter explains the global cache administration mechanism used by ADempiere.

The previous chapter explained CCache, the lightweight HashMap-based cache implementation used throughout the Core.

This chapter explains CacheMgt, the global cache manager responsible for registering, coordinating and resetting cache instances across the application.


Source File

source/base/src/org/compiere/util/CacheMgt.java

Package:

org.compiere.util

Architectural Position

Business Model
      │
      ▼
CCache
      │
      ▼
CacheInterface
      │
      ▼
CacheMgt

CCache stores cached objects.

CacheMgt coordinates cache instances globally.


Singleton Design

CacheMgt is implemented as a Singleton.

public static synchronized CacheMgt get()

Conceptually:

Application
      │
      ▼
CacheMgt.get()
      │
      ▼
Single Global Cache Manager

Only one CacheMgt instance exists during the application lifecycle.


Internal Structure

Source code inspection confirms that CacheMgt maintains two collections.

private ArrayList<CacheInterface> m_instances;
private ArrayList<String> m_tableNames;

The first collection stores cache objects.

The second stores their associated table names.

Conceptually:

CacheMgt

├── m_instances
│     ├── CCache AD_Client
│     ├── CCache C_AcctSchema
│     ├── CCache AD_Table
│     └── ...
│
└── m_tableNames
      ├── AD_Client
      ├── C_AcctSchema
      ├── AD_Table
      └── ...

Cache Registration

Every CCache registers itself automatically.

Registration flow:

new CCache(...)
      │
      ▼
CacheMgt.get().register(this)
      │
      ▼
m_instances.add(cache)
      │
      ▼
m_tableNames.add(cacheName)

This centralized registration enables global cache administration.


CacheInterface

CacheMgt operates against the generic interface:

CacheInterface

instead of concrete cache implementations.

This allows any cache implementation conforming to the interface to participate in global cache management.


Reset All Caches

The method

reset()

iterates through every registered cache.

Conceptually:

CacheMgt.reset()
      │
      ▼
Iterate registered caches
      │
      ▼
cache.reset()
      │
      ▼
Return total removed elements

This operation clears all registered cache instances.


Reset by Table Name

CacheMgt also supports targeted invalidation.

reset(String tableName)

internally delegates to

reset(String tableName, int Record_ID)

Conceptually:

CacheMgt.reset("C_Period")
      │
      ▼
Locate caches
      │
      ▼
Reset matching caches

This provides a more selective alternative to a global reset.


Prefix Matching Strategy

One interesting implementation detail discovered during source code analysis is:

cc.getName().startsWith(tableName)

Instead of exact matching, CacheMgt performs prefix matching.

Example:

C_Period

↓

C_Period
C_PeriodControl

Both caches are reset.

This behavior allows related cache structures to be invalidated together.


Record_ID Parameter

The method signature accepts:

reset(String tableName, int Record_ID)

However, the inspected implementation resets the entire matching cache.

The supplied Record_ID is currently not used for entry-level invalidation.

Conceptually:

reset(tableName, Record_ID)

↓

Matching cache

↓

Complete cache reset

Relationship with PO

The persistence layer interacts directly with CacheMgt.

Whenever a persistent object is saved or deleted, the corresponding table cache may be invalidated.

Conceptually:

PO.save()

↓

Database Update

↓

CacheMgt.reset(tableName)

↓

Cached Metadata Invalidated

This mechanism keeps cached metadata synchronized with database changes while avoiding unnecessary global cache resets.


Common Usage Examples

Source code inspection identified several usages throughout the Core framework.

Examples include:

CacheMgt.get().reset();
CacheMgt.get().reset("AD_Message");
CacheMgt.get().reset("ImageElement");
CacheMgt.get().reset("C_Period");
CacheMgt.get().reset("C_PeriodControl");

These examples confirm that CacheMgt is used by multiple Core components including:

  • Environment initialization
  • Developer Mode
  • Financial Reports
  • Persistence Layer (PO)
  • Period Management
  • Application Dictionary

Element Count

CacheMgt can calculate the total number of cached objects currently held in memory.

Method:

getElementCount()

For CCache instances the implementation uses:

sizeNoExpire()

instead of the regular size().

This allows CacheMgt to inspect cache contents without triggering lazy expiration.

Conceptually:

CacheMgt

↓

Iterate CCache

↓

sizeNoExpire()

↓

Total Cached Elements

Complete Cache Lifecycle

The complete lifecycle of a cache inside ADempiere can be summarized as follows.

Business Model

↓

Static CCache

↓

CCache Constructor

↓

CacheMgt.register()

↓

Application Runtime

↓

Cache Hit / Cache Miss

↓

PO.save()

↓

Database Update

↓

CacheMgt.reset()

↓

CCache.reset()

↓

Cache Rebuilt on Demand

This architecture separates three responsibilities:

  • Storage (CCache)
  • Administration (CacheMgt)
  • Persistence (PO)

Relationship with the Accounting Engine

Although CacheMgt is part of the Core framework, it has a direct impact on the Accounting Engine.

Accounting processes continuously reuse cached metadata such as:

  • Accounting Schemas
  • Accounting Combinations
  • Organizations
  • Clients
  • Tables
  • Periods

Whenever accounting metadata changes, CacheMgt guarantees that obsolete cache entries are discarded before they can affect future postings.


BLACK ERP Engineering Notes

For BLACK ERP development, understanding CacheMgt is especially important when implementing:

  • New Application Dictionary elements
  • SAT localization metadata
  • Accounting customizations
  • Dynamic configuration tables
  • New model classes
  • Custom business processes

If metadata changes are not immediately reflected by the application, developers should verify whether the issue is related to cache invalidation before investigating database or source code problems.


Engineering Considerations

Source code analysis reveals several practical considerations.

  • CacheMgt is intentionally lightweight.
  • Cache administration is centralized.
  • CCache remains responsible only for storage.
  • Cache registration occurs automatically.
  • Global reset is available when required.
  • Table-based reset minimizes unnecessary cache invalidation.
  • Prefix matching allows dependent cache structures to be refreshed together.

This design favors simplicity and maintainability over complex cache management algorithms.


Engineering Principles

The Cache Management subsystem follows several architectural principles.

  • Separation of responsibilities.
  • Centralized cache administration.
  • Automatic cache registration.
  • Lightweight implementation.
  • Predictable invalidation behavior.
  • Transparent integration with the persistence layer.

These principles contribute to the stability and performance of the ADempiere Core.


Key Takeaways

  • CacheMgt is the global cache manager of ADempiere.
  • It is implemented as a Singleton.
  • Cache instances register automatically.
  • Registered caches are managed through CacheInterface.
  • Global cache reset is supported.
  • Table-specific cache reset is also supported.
  • Prefix matching refreshes dependent cache structures.
  • PO uses CacheMgt to maintain cache consistency after persistence operations.
  • The Accounting Engine benefits directly from this centralized cache management architecture.

Conclusion

The combination of CCache and CacheMgt provides a simple yet highly effective caching architecture.

Rather than relying on sophisticated cache algorithms, ADempiere achieves excellent performance through:

  • Lightweight cache implementation.
  • Centralized administration.
  • Automatic registration.
  • Lazy expiration.
  • Explicit invalidation after metadata changes.

This approach has proven sufficiently robust to support the entire ERP framework while keeping the implementation understandable and maintainable.


Next Chapter

Chapter 17 concludes the KB-212 series by presenting the complete architectural view of the Accounting Engine and its interaction with the Persistence Framework, Transaction Manager, Cache Architecture and PostgreSQL.


Revision History

Version Date Description
1.6 2026-06-27 Added complete CacheMgt architecture based on source code analysis of CacheMgt.java, including registration, global administration, cache invalidation and relationship with the Persistence Framework.