Security & Caching
Field-Level Encryption and JSR-107 (JCache) Integration
What Morphium Offers
Two independent Morphium-core capabilities beyond ORM basics: field-level encryption, which transparently encrypts individual entity fields before they hit MongoDB and decrypts them on load, and a JSR-107 (JCache)-backed cache implementation as a drop-in alternative to Morphium's default in-memory cache.
The Challenge
Sensitive fields (secrets, PII) need encryption at rest without every read/write path in the application having to encrypt/decrypt by hand. Separately, applications that already standardize on a JSR-107 cache provider (EHCache, Hazelcast, ...) for the rest of their stack shouldn't need a second, incompatible caching mechanism just for Morphium.
Morphium Features Used
Prerequisites & Key Concepts
- Encryption keys must exist before first use. Register them via
morphium.getEncryptionKeyProvider()at application startup (e.g. a CDI@PostConstruct) — there is no automatic key generation. - A normal query can never prove encryption.
morphium.createQueryFor(Entity.class).get()always returns the transparently-decrypted value, by design. To see the ciphertext, you must read the raw MongoDB document via the low-level driver, bypassing the object mapper entirely. - The cache implementation is chosen per Morphium instance, at
configuration time —
cacheSettings().setCache(...)must be set before the instance connects, and cannot be swapped afterwards. Because the CDI-injectedMorphiumalready uses the default cache for every other feature in this showcase, the JCache demo below runs against a second, independentMorphiuminstance rather than reconfiguring the shared one. - Cache activation is annotation-driven either way. Switching cache
implementations changes how caching works under the hood, not which
entities are cached — that remains controlled by
@Cacheon the entity, same as the Product Catalog's non-JCache caching demo.
Field-Level Encryption: Entity Source Code
SecureNote.java
Java
import de.caluga.morphium.annotations.encryption.Encrypted; import de.caluga.morphium.encryption.AESEncryptionProvider; @Entity(collectionName = "secure_notes") public class SecureNote { @Id private MorphiumId id; private String title; // plaintext @Encrypted(provider = AESEncryptionProvider.class, keyName = "secure-note-key")1 private String secretContent; }
1 Everything else about this field is ordinary Java — no manual encrypt/decrypt calls anywhere in application code.
Registering keys and proving ciphertext
Java
@PostConstruct void ensureKeys() {1 morphium.getEncryptionKeyProvider().setEncryptionKey(KEY_NAME, DEMO_KEY); morphium.getEncryptionKeyProvider().setDecryptionKey(KEY_NAME, DEMO_KEY); } // Bypasses the object mapper entirely -- returns the document exactly as MongoDB stores it FindCommand fc = new FindCommand(morphium.getDriver().getPrimaryConnection(null))2 .setDb(morphium.getDatabase()) .setColl(morphium.getMapper().getCollectionName(SecureNote.class)) .setFilter(Map.of("_id", note.getId())); List<Map<String,Object>> raw = fc.execute(); // raw.get(0).get("secretContent") is a byte[] -- ciphertext, not the plaintext string
1 Must run before the first store()/query touching an @Encrypted field.
2 This is the only way to see the raw ciphertext -- a normal query always decrypts transparently.
JCache: Standalone Instance Setup
Configuring a second Morphium instance with JCache
Java
MorphiumConfig cfg = new MorphiumConfig(); cfg.connectionSettings().setDatabase("showcase-jcache-demo");1 cfg.driverSettings().setDriverName(InMemoryDriver.driverName); cfg.cacheSettings().setCache(new MorphiumCacheJCacheImpl());2 Morphium jcacheMorphium = new Morphium(cfg);3
1 A separate database name keeps this instance's data isolated from the rest of the showcase.
2 Must be set on the config before constructing the instance — if left unset, Morphium defaults to its own in-memory cache during initialization.
3 The constructor connects synchronously; no separate
.connect() call needed.Related Documentation
- Security Guide — @Encrypted, EncryptionKeyProvider
- Developer Guide — @Cache, MorphiumCache