---
title: Persist preferences
summary: Writes accumulated in-memory preference changes for the current application to the Oracle-backed preference store.
status: draft
owner: SAIF Documentation Team
last_reviewed: 2026-08-17
library: SAIF.Presentation
reference_type: package
operation_id: OP-PREF-004
trigger: Consumer code calls Save()
---

# Persist preferences

This operation writes all in-memory preference groups belonging to the current application back to the Oracle-backed store, delegating the actual persistence call to `SAIF.Framework.Preferences.PreferenceData`. Its boolean return value cannot be used to detect success ([BR-PREF-004](../business-rules.md#br-pref-004-save-return-value-is-unreliable)).

| Field | Value |
| --- | --- |
| **Operation ID** | OP-PREF-004 |
| **Trigger** | Consumer code calls `Save()` |
| **Inputs** | None (uses in-memory `_Preferences` and `m_DPI`) |
| **Outputs** | `Boolean` (always `False`, see [BR-PREF-004](../business-rules.md#br-pref-004-save-return-value-is-unreliable)); persisted rows in the Oracle preference store |
| **Primary components** | `clsPreferences.Save` |
| **Entry point** | SAIF.Presentation\clsPreferences.vb |

## Steps

1. `clsLogTrace.MethodBegin()` is called at the start of the method — note that the corresponding `MethodEnd()` call is unreachable dead code (see step 5) ([BR-PREF-004](../business-rules.md#br-pref-004-save-return-value-is-unreliable)).
2. Constructs `PreferenceData(m_DPI)`.
3. For each `Preference` group in `_Preferences` whose `ApplicationName = m_Application` ([BR-PREF-003](../business-rules.md#br-pref-003-save-scoped-to-current-application)), calls `prefdata.SavePreferences(pref.ApplicationName, pref.Pagename, m_DPI.UserID, json)` where `json` is `Serializer.Serialize(pref.PreferenceItems)` if the group has any items, else an empty string.
   - This step delegates to logic implemented in `SAIF.Framework.Preferences.PreferenceData`, an external dependency library not present in this repository.

   > **Origin**: The persistence SQL/BOF logic behind `SavePreferences` is implemented in `PreferenceData` (`SAIF.Framework.Preferences`) and is out of scope for this library's analysis — its internal steps could not be traced here**.
   - On failure: any exception during the loop is caught and rethrown wrapped as `ApplicationException("Unable to save preferences.", ex)`.
4. On any exception, wraps and rethrows as `ApplicationException("Unable to save preferences.", ex)`.
5. Returns `result`, which is always `False` because `Return result` executes before the trailing `clsLogTrace.MethodEnd()` call, and `result` is never set to `True` anywhere in the method body ([BR-PREF-004](../business-rules.md#br-pref-004-save-return-value-is-unreliable)) — callers checking the return value for success will always see `False` even on a fully successful save.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Save called]) --> S1[Construct PreferenceData with m_DPI]
	S1 --> S2[For each Preference group matching m_Application]
	S2 --> S3[Serialize PreferenceItems to JSON]
	S3 --> S4[Call PreferenceData.SavePreferences]
	S4 --> S5{Exception thrown?}
	S5 -->|Yes| EndErr([Throw ApplicationException])
	S5 -->|No| EndOk([Return False, regardless of outcome])
```

## Failure and edge-case behavior

- Any exception raised while saving any group is caught and rethrown as `ApplicationException("Unable to save preferences.", ex)`; the underlying exception is preserved as the inner exception.
- The `Boolean` return value is always `False`, even on full success — callers must rely solely on the absence of a thrown exception to infer success ([BR-PREF-004](../business-rules.md#br-pref-004-save-return-value-is-unreliable)).
- Only preference groups matching the current `m_Application` are saved; groups for other applications loaded in the same user session are silently skipped ([BR-PREF-003](../business-rules.md#br-pref-003-save-scoped-to-current-application)).

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- SAIF.Presentation\clsPreferences.vb
