Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Best Practices for Data Storage using SAL PluginSettings (Confluence 9/10)

When developing or updating apps for Confluence 9/10, PluginSettingsFactory (SAL) is the standard API for data storage.

Because SAL is a single, global flat key-value store, there are two major architectural best practices you should follow to ensure your data is safe and easily retrievable:

  1. Unique Key Prefixes: Since there are no isolated contexts, you must use unique prefixes to prevent your keys from clashing with other plugins.

  2. Strict Serialization: SAL is strict about data types. It is highly recommended to serialize all custom objects to JSON Strings before saving them.

Here is a clean, generic pattern for reading and writing data using pure SAL..

 

1. Flattening your Keys

In Bandana, you had a Context and a Key. In SAL, you must combine these into a single, unique String key to prevent overriding other plugins' data.

The Old Way (Bandana):


private static final BandanaContext CONTEXT = new ConfluenceBandanaContext("my.plugin.context");
// Saved as: Context="my.plugin.context", Key="config_SPACEA"

The New Way (SAL):


// Define a unique flat key prefix for your plugin
private static final String SAL_KEY_PREFIX = "my.plugin.config_";

// Example: When saving data for a specific space, your final key becomes:
// "my.plugin.config_SPACEA"

 

2. Writing Data (Using Gson for Serialization)

When saving data to SAL, convert your configuration objects to JSON. This ensures your data structure remains perfectly intact and avoids casting errors when retrieving it.

 


public void saveSpaceConfig(String spaceKey, MyConfigData configData) {
PluginSettings settings = pluginSettingsFactory.createGlobalSettings();
Gson gson = new Gson();

// 1. Create the unique flat key
String flatKey = "my.plugin.config_" + spaceKey;

// 2. Serialize the object to JSON and save to SAL
String jsonString = gson.toJson(configData);
settings.put(flatKey, jsonString);
}

 

 

3. Reading Data

When retrieving your data, you simply fetch the string using your flat key and deserialize it back into your Java object.

 


public MyConfigData getSpaceConfig(String spaceKey) {
PluginSettings settings = pluginSettingsFactory.createGlobalSettings();
Gson gson = new Gson();

String flatKey = "my.plugin.config_" + spaceKey;

// 1. Fetch the data from the SAL database
String jsonConfig = (String) settings.get(flatKey);

// 2. Check if it exists, then deserialize and return
if (jsonConfig != null && !jsonConfig.trim().isEmpty()) {
return gson.fromJson(jsonConfig, MyConfigData.class);
}

// Return null or a default configuration if no data is found
return null;
}

 

1 comment

Martin Runge
Community Champion
August 27, 2026

Hi @Pratik Sunil Lodha, just a quick note that I moved this from the Confluence questions board over to Confluence articles. It reads as a how to guide rather than a question, so it fits better here and is easier for others to find later.

Thanks for sharing the pattern.

Cheers, Martin

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events