KB-212 – Accounting Engine Architecture¶
Knowledge Base ID: KB-212
Chapter: 15 - CCache & Object Caching Architecture
Project: BLACK ERP
Version: 1.5
Status: Draft
Last Updated: 2026-06-27
Applies To: ADempiere 3.9.4
Purpose¶
This chapter explains the in-memory caching architecture used throughout ADempiere.
Although the Accounting Engine appears to retrieve accounting metadata directly from the database, the Core framework relies heavily on an object cache implementation named CCache.
Understanding this component is essential for developing high-performance customizations while minimizing unnecessary database access.
Unlike many modern cache frameworks, ADempiere implements a lightweight and centralized caching strategy that is reused consistently across the entire application.
Why Caching Matters¶
Without object caching, nearly every business transaction would repeatedly query PostgreSQL for metadata.
Typical examples include:
- Accounting Schemas
- Clients
- Organizations
- Roles
- Tables
- Columns
- Products
- Taxes
- Document Types
- Periods
- Currency Definitions
- Accounting Combinations
Caching dramatically reduces the number of SQL statements executed during normal ERP operation.
High-Level Architecture¶
Conceptually, the Core follows this architecture.
Business Logic
↓
Business Model
↓
CCache
↓
Database
Whenever possible, objects are retrieved directly from memory.
Database access occurs only when the requested object is not already cached.
Internal Design¶
One of the most important discoveries during the source code review is that CCache is intentionally lightweight.
Rather than implementing a sophisticated caching engine, ADempiere extends the standard Java collection framework.
Conceptually:
HashMap
↓
CCache
↓
CacheInterface
The implementation is based on:
public class CCache<K,V>
extends HashMap<K,V>
implements CacheInterface
This design keeps the implementation simple while allowing every Core component to share the same caching behavior.
Cache Registration¶
Every cache automatically registers itself inside the global cache manager.
Conceptually:
New CCache
↓
CacheMgt.register()
↓
Global Cache Registry
This centralized registration allows ADempiere to manage every cache instance consistently across the application.
Cache Hit¶
When an object already exists inside memory:
Request
↓
CCache
↓
Hit
↓
Return Object
No SQL statement is executed.
The object is returned immediately.
Cache Miss¶
If the object is not yet available:
Request
↓
CCache
↓
Database
↓
Instantiate Object
↓
Store in Cache
↓
Return Object
Future requests reuse the cached instance.
Expiration Strategy¶
Unlike many cache frameworks, ADempiere does not continuously monitor cache expiration.
Instead, expiration is evaluated only when the cache is accessed.
Conceptually:
get()
↓
expire()
↓
Expired ?
↓
YES
↓
reset()
↓
clear()
↓
Continue
This lazy expiration strategy keeps the implementation extremely efficient.
No background cleanup thread is required.
Cache Reset¶
When a cache expires, ADempiere performs a complete reset.
Conceptually:
Expired
↓
reset()
↓
clear()
↓
Empty Cache
The framework does not remove entries individually.
Instead, the entire cache is cleared and rebuilt progressively as objects are requested again.
Cache Lifetime¶
Each cache may define its own expiration policy.
Typical configurations include:
0
↓
Never Expire
5
↓
Five Minutes
60
↓
One Hour
120
↓
Two Hours
Different business objects use different expiration periods depending on how frequently their metadata changes.
Cached Objects¶
Source code inspection confirms that CCache is used extensively throughout ADempiere.
Examples include:
- MAcctSchema
- MClient
- MRole
- MTable
- MColumn
- MProduct
- MTax
- MDocType
- MWorkflow
- MPeriod
- MBankAccount
- MCurrency
- POInfo
- Trx
- Msg
These are only representative examples.
The cache implementation is shared by a very large portion of the Core framework.
Relationship with the Accounting Engine¶
During document posting, accounting metadata is resolved repeatedly.
Instead of querying PostgreSQL for every operation:
Doc
↓
MAccount
↓
MAcctSchema
↓
CCache
↓
Memory
The Posting Engine therefore minimizes metadata-related database traffic.
Performance Benefits¶
The caching architecture provides several important advantages.
- Reduced SQL execution
- Faster document posting
- Lower PostgreSQL workload
- Lower latency
- Improved scalability
- Faster metadata access
- Better UI responsiveness
The simplicity of the implementation contributes to its reliability.
Engineering Considerations¶
Developers should understand that cached objects may remain in memory after metadata changes.
Whenever metadata is modified programmatically, cache invalidation may become necessary.
Typical scenarios include:
- Dictionary modifications
- New accounting schemas
- New accounting combinations
- Metadata synchronization
- System configuration updates
Ignoring cache consistency may produce unexpected application behavior.
BLACK ERP Example¶
During the Mexican VAT Cash Basis implementation, additional accounting metadata is resolved multiple times while posting allocations.
Conceptually:
Allocation
↓
MXVATCashBasisEngine
↓
Resolve Accounts
↓
CCache
↓
FactLine
Because accounting metadata is already cached, repeated postings avoid unnecessary metadata queries.
This improves posting performance while preserving transactional consistency.
Engineering Principles¶
The source code demonstrates several important architectural principles.
- Cache implementation is intentionally lightweight.
- CCache extends Java HashMap.
- Every cache is centrally registered.
- Expiration is evaluated lazily.
- Cache reset clears the entire cache.
- Business logic remains completely unaware of caching.
- Performance optimization is transparent to application code.
Key Takeaways¶
- CCache is the standard caching mechanism used throughout ADempiere.
- The implementation extends Java HashMap.
- Cache instances are centrally managed.
- Expiration occurs only during cache access.
- Expired caches are completely reset.
- Hundreds of Core operations depend on cached metadata.
- The Accounting Engine benefits directly from this architecture.
Next Chapter¶
Chapter 16 explores CacheMgt, the global cache manager responsible for registering, coordinating and administrating every cache instance used throughout the ADempiere Core.
Revision History¶
| Version | Date | Description |
|---|---|---|
| 1.5 | 2026-06-27 | Rewritten after source code analysis of CCache.java. Added internal architecture, cache registration, lazy expiration, reset strategy and real implementation details based on ADempiere 3.9.4 source code. |