This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit c1616c8e037fb4a80c9fccf9c7cf780e697b60ae
Author: Andrus Adamchik <[email protected]>
AuthorDate: Wed May 20 09:43:50 2026 -0400

    Modeler prefs - removing unused nodes
---
 .../org/apache/cayenne/modeler/Application.java    | 12 +--
 .../cayenne/modeler/NameGeneratorPreferences.java  |  2 +-
 .../apache/cayenne/modeler/pref/DataMapPrefs.java  |  2 +-
 .../apache/cayenne/modeler/pref/DataNodePrefs.java |  4 +-
 .../cayenne/modeler/pref/PreferenceMigration.java  |  2 +-
 .../apache/cayenne/modeler/pref/PrefsLocator.java  | 16 ++--
 .../{PrefsRepository.java => PrefsManager.java}    | 78 +++++-------------
 .../toV5/_8_RemoveRedundantPathIndexMigration.java | 83 +++++++++++++++++++
 .../cayenne/modeler/project/ProjectPrefs.java      |  4 +-
 .../cayenne/modeler/project/ProjectSession.java    |  8 +-
 .../component/CMComponentGeometryPrefs.java        |  4 +-
 .../toolkit/filechooser/CMFileChooserPrefs.java    |  4 +-
 .../toolkit/splitpane/CMSplitPanePrefs.java        |  4 +-
 .../modeler/toolkit/table/CMTablePrefs.java        |  6 +-
 .../org/apache/cayenne/modeler/ui/MainFrame.java   |  4 +-
 .../modeler/ui/action/DBConnectionAwareAction.java |  2 +-
 .../modeler/ui/action/ImportDataMapAction.java     |  2 +-
 .../modeler/ui/action/ImportEOModelAction.java     |  2 +-
 .../cayenne/modeler/ui/action/SaveAsAction.java    |  4 +-
 .../modeler/ui/datasource/DataSourceDialog.java    |  4 +-
 .../modeler/ui/dbgen/DBGeneratorOptionsDialog.java |  2 +-
 .../cayenne/modeler/ui/dbgen/DBGeneratorPrefs.java |  4 +-
 .../ui/dbrelationship/DbRelationshipDialog.java    |  2 +-
 .../preferences/classpath/ClasspathPrefsPanel.java |  2 +-
 .../ui/preferences/more/MorePrefsPanel.java        |  2 +-
 .../cayenne/modeler/ui/project/ProjectView.java    |  2 +-
 .../editor/datadomain/main/DataDomainMainView.java |  2 +-
 .../cgen/templateeditor/TemplateEditor.java        |  4 +-
 .../editor/datamap/main/DataMapMainView.java       |  4 +-
 .../editor/datanode/DataNodeEditorPanel.java       |  4 +-
 .../editor/datanode/jdbc/JDBCDataSourcePanel.java  |  2 +-
 .../dbentity/properties/DbAttributePanel.java      |  2 +-
 .../properties/DbEntityPropertiesView.java         |  2 +-
 .../dbentity/properties/DbRelationshipPanel.java   |  2 +-
 .../attributes/EmbeddableAttributesView.java       |  2 +-
 .../objentity/attrinfo/ObjAttributeInfoDialog.java |  2 +-
 .../callbacks/ObjEntityCallbacksView.java          |  4 +-
 .../objentity/properties/ObjAttributePanel.java    |  2 +-
 .../properties/ObjEntityPropertiesView.java        |  2 +-
 .../objentity/properties/ObjRelationshipPanel.java |  2 +-
 .../editor/procedure/ProcedureParameterTab.java    |  2 +-
 .../query/selectquery/SelectQueryOrderingTab.java  |  2 +-
 .../query/sqltemplate/SQLTemplatePrefetchTab.java  |  2 +-
 .../_8_RemoveRedundantPathIndexMigrationTest.java  | 94 ++++++++++++++++++++++
 44 files changed, 272 insertions(+), 125 deletions(-)

diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
index f5c943c75..9ffb75038 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/Application.java
@@ -35,7 +35,7 @@ import org.apache.cayenne.modeler.pref.ClasspathPrefs;
 import org.apache.cayenne.modeler.pref.DBConnectorPrefs;
 import org.apache.cayenne.modeler.pref.GeneralPrefs;
 import org.apache.cayenne.modeler.pref.PrefsLocator;
-import org.apache.cayenne.modeler.pref.PrefsRepository;
+import org.apache.cayenne.modeler.pref.PrefsManager;
 import org.apache.cayenne.modeler.pref.RecentProjectsPrefs;
 import org.apache.cayenne.modeler.service.action.GlobalActions;
 import org.apache.cayenne.modeler.service.classloader.ModelerClassLoader;
@@ -90,7 +90,7 @@ public class Application {
     private final UIInitializer platformInit;
     private final ModelerClassLoader classLoader;
     private final PrefsLocator prefsLocator;
-    private final PrefsRepository prefsRepository;
+    private final PrefsManager prefsManager;
     private final ProjectValidator projectValidator;
     private final CliArgs cli;
     private GlobalActions actionManager;
@@ -106,7 +106,7 @@ public class Application {
 
         this.classLoader = new ModelerClassLoader();
         this.prefsLocator = new PrefsLocator();
-        this.prefsRepository = new 
PrefsRepository(injector.getInstance(ConfigurationNameMapper.class), 
prefsLocator);
+        this.prefsManager = new 
PrefsManager(injector.getInstance(ConfigurationNameMapper.class), prefsLocator);
         this.projectValidator = new ConfigurableProjectValidator(this);
     }
 
@@ -185,7 +185,7 @@ public class Application {
         this.logConsole = new LogConsole(this);
         ModelerLogFactory.setAppender(logConsole);
 
-        getPrefsRepository().runMigrations();
+        getPrefsManager().runMigrations();
 
         this.dbConnectors = new DBConnectorPrefs(prefsLocator).getConnectors();
 
@@ -226,8 +226,8 @@ public class Application {
         return dbConnectors;
     }
 
-    public PrefsRepository getPrefsRepository() {
-        return prefsRepository;
+    public PrefsManager getPrefsManager() {
+        return prefsManager;
     }
 
     public PrefsLocator getPrefsLocator() {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/NameGeneratorPreferences.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/NameGeneratorPreferences.java
index 7d0fdac0c..06d41e6b7 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/NameGeneratorPreferences.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/NameGeneratorPreferences.java
@@ -48,7 +48,7 @@ public class NameGeneratorPreferences {
     }
 
     Preferences getPreference(Application application) {
-        return 
application.getPrefsRepository().projectPref(application.getFrame().getProjectSession().project(),
 null);
+        return 
application.getPrefsManager().projectPref(application.getFrame().getProjectSession().project(),
 null);
     }
 
     /**
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DataMapPrefs.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DataMapPrefs.java
index 8e48efb2f..c9a772117 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DataMapPrefs.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DataMapPrefs.java
@@ -26,7 +26,7 @@ public final class DataMapPrefs extends PreferenceAdapter {
     public static final String SUPERCLASS_PACKAGE_PROPERTY = 
"superclassPackage";
     public static final String DEFAULT_SUPERCLASS_PACKAGE_SUFFIX = "auto";
 
-    public DataMapPrefs(PrefsRepository repository, DataMap dataMap) {
+    public DataMapPrefs(PrefsManager repository, DataMap dataMap) {
         super(repository.dataMapPref(dataMap, null));
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DataNodePrefs.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DataNodePrefs.java
index 649dd2f10..2dc785c4f 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DataNodePrefs.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/DataNodePrefs.java
@@ -26,12 +26,12 @@ public final class DataNodePrefs extends PreferenceAdapter {
 
     static final String NODE = "dataNode";
 
-    private final PrefsRepository repository;
+    private final PrefsManager repository;
     private final Project project;
 
     private String localDataSource;
 
-    public DataNodePrefs(PrefsRepository repository, Project project, String 
dataNodeName) {
+    public DataNodePrefs(PrefsManager repository, Project project, String 
dataNodeName) {
         super(repository.projectPref(project, NODE + "/" + dataNodeName));
 
         // capture repo and project for the sake of "rename"
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferenceMigration.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferenceMigration.java
index 126aec70e..1d3bc6fb4 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferenceMigration.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferenceMigration.java
@@ -19,7 +19,7 @@
 package org.apache.cayenne.modeler.pref;
 
 /**
- * One-time data migration applied by {@link PrefsRepository#runMigrations()}.
+ * One-time data migration applied by {@link PrefsManager#runMigrations()}.
  */
 public interface PreferenceMigration {
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsLocator.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsLocator.java
index 0e35c4558..693cdee77 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsLocator.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsLocator.java
@@ -21,11 +21,7 @@ package org.apache.cayenne.modeler.pref;
 import java.util.prefs.Preferences;
 
 /**
- * Maps logical Modeler preference locations to {@link Preferences} nodes. Pure
- * JDK; holds the layout constants for {@code 
org/apache/cayenne/modeler/v5/...}
- * (the regular preferences tree) and {@code 
org/apache/cayenne/modeler/mcp-handshake/...}
- * (the sibling MCP launch-handshake namespace). All Modeler code that 
addresses
- * a preferences node should go through this class.
+ * Resolves preference nodes against the common root.
  */
 public final class PrefsLocator {
 
@@ -43,7 +39,15 @@ public final class PrefsLocator {
     private final Preferences root;
 
     public PrefsLocator() {
-        this.root = Preferences.userRoot();
+        this(Preferences.userRoot());
+    }
+
+    /**
+     * Test-friendly constructor letting callers point the locator at an 
isolated
+     * preferences subtree instead of {@link Preferences#userRoot()}.
+     */
+    public PrefsLocator(Preferences root) {
+        this.root = root;
     }
 
     /**
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsRepository.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsManager.java
similarity index 81%
rename from 
modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsRepository.java
rename to 
modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsManager.java
index 1fef1f666..31a7935f3 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsRepository.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PrefsManager.java
@@ -27,6 +27,7 @@ import 
org.apache.cayenne.modeler.pref.migration.toV5._4_RecentProjectsMigration
 import 
org.apache.cayenne.modeler.pref.migration.toV5._5_FrameGeometryMigration;
 import 
org.apache.cayenne.modeler.pref.migration.toV5._6_ProjectSplitPaneMigration;
 import 
org.apache.cayenne.modeler.pref.migration.toV5._7_EntityTablePrefsMigration;
+import 
org.apache.cayenne.modeler.pref.migration.toV5._8_RemoveRedundantPathIndexMigration;
 import org.apache.cayenne.configuration.ConfigurationNameMapper;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.resource.Resource;
@@ -47,25 +48,19 @@ import java.util.stream.Stream;
 
 
 /**
- * App-wide preferences service for the Modeler. Delegates preferences-node
- * location to {@link PrefsLocator} and adds Modeler-specific lifecycle
- * on top: tracking unsaved projects/DataMaps with in-memory ids, staging
- * renames/moves so they can be replayed on save, running version-gated
- * preference migrations, and resetting the subtree.
+ * A stateful preferences manager for the Application. Handles preference 
versioning, DataMap and project renaming,
+ * locating preference nodes under the common root, etc.
  */
-public class PrefsRepository {
+public class PrefsManager {
 
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(PrefsRepository.class);
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(PrefsManager.class);
 
-    private static final String PROJECT_INDEX_NODE = "projectIndex";
-    private static final String DATAMAP_INDEX_NODE = "dataMapIndex";
     private static final String UNSAVED_PREFIX = "unsaved-";
 
     private static final String UI_NODE = "ui";
     private static final String META_NODE = "_meta";
 
     private static final String MIGRATIONS_VERSION_KEY = 
"migrationsAppliedVersion";
-    private static final String PATH_KEY = "path";
 
     private final ConfigurationNameMapper nameMapper;
     private final List<PreferenceMigration> migrations;
@@ -84,14 +79,15 @@ public class PrefsRepository {
                         new _4_RecentProjectsMigration(),
                         new _5_FrameGeometryMigration(),
                         new _6_ProjectSplitPaneMigration(),
-                        new _7_EntityTablePrefsMigration())
+                        new _7_EntityTablePrefsMigration(),
+                        new _8_RemoveRedundantPathIndexMigration())
 
                 // just in case, sort to prevent any ordering issues with 
manual insertion
                 .sorted(Comparator.comparingInt(PreferenceMigration::version))
                 .collect(Collectors.toList());
     }
 
-    public PrefsRepository(ConfigurationNameMapper nameMapper, PrefsLocator 
locator) {
+    public PrefsManager(ConfigurationNameMapper nameMapper, PrefsLocator 
locator) {
         this.nameMapper = nameMapper;
         this.locator = locator;
         this.migrations = toV5Migrations();
@@ -105,16 +101,11 @@ public class PrefsRepository {
      * Returns the preferences node for the given {@link Project}, optionally 
descending into a subtree within it.
      */
     public Preferences projectPref(Project project, String relativePath) {
-        Preferences node;
         String path = projectPath(project);
-        if (path != null) {
-            String id = PreferenceNodeIds.idForPath(path);
-            node = locator.projectNode(id);
-            recordPath(node, id, path, PROJECT_INDEX_NODE);
-        } else {
-            String id = newProjectIds.computeIfAbsent(project, p -> 
newUnsavedId());
-            node = locator.projectNode(id);
-        }
+        String id = path != null
+                ? PreferenceNodeIds.idForPath(path)
+                : newProjectIds.computeIfAbsent(project, p -> newUnsavedId());
+        Preferences node = locator.projectNode(id);
         return relativePath == null || relativePath.isEmpty() ? node : 
node.node(relativePath);
     }
 
@@ -133,16 +124,11 @@ public class PrefsRepository {
      * Returns the preferences node for the given {@link DataMap}, optionally 
descending into a subtree within it.
      */
     public Preferences dataMapPref(DataMap map, String relativePath) {
-        Preferences node;
         String path = dataMapPath(map);
-        if (path != null) {
-            String id = PreferenceNodeIds.idForPath(path);
-            node = locator.dataMapNode(id);
-            recordPath(node, id, path, DATAMAP_INDEX_NODE);
-        } else {
-            String id = newDataMapIds.computeIfAbsent(map, m -> 
newUnsavedId());
-            node = locator.dataMapNode(id);
-        }
+        String id = path != null
+                ? PreferenceNodeIds.idForPath(path)
+                : newDataMapIds.computeIfAbsent(map, m -> newUnsavedId());
+        Preferences node = locator.dataMapNode(id);
         return relativePath == null || relativePath.isEmpty() ? node : 
node.node(relativePath);
     }
 
@@ -310,18 +296,14 @@ public class PrefsRepository {
         if (stagedOldPath != null) {
             String oldId = PreferenceNodeIds.idForPath(stagedOldPath);
             if (!oldId.equals(savedId)) {
-                relocate(locator::projectNode, oldId, savedId, 
PROJECT_INDEX_NODE, currentPath);
-            } else {
-                recordPath(locator.projectNode(savedId), savedId, currentPath, 
PROJECT_INDEX_NODE);
+                relocate(locator::projectNode, oldId, savedId);
             }
             return;
         }
 
         String oldId = newProjectIds.remove(project);
         if (oldId != null && !oldId.equals(savedId)) {
-            relocate(locator::projectNode, oldId, savedId, PROJECT_INDEX_NODE, 
currentPath);
-        } else {
-            recordPath(locator.projectNode(savedId), savedId, currentPath, 
PROJECT_INDEX_NODE);
+            relocate(locator::projectNode, oldId, savedId);
         }
     }
 
@@ -336,35 +318,19 @@ public class PrefsRepository {
         if (stagedOldPath != null) {
             String oldId = PreferenceNodeIds.idForPath(stagedOldPath);
             if (!oldId.equals(savedId)) {
-                relocate(locator::dataMapNode, oldId, savedId, 
DATAMAP_INDEX_NODE, currentPath);
-            } else {
-                recordPath(locator.dataMapNode(savedId), savedId, currentPath, 
DATAMAP_INDEX_NODE);
+                relocate(locator::dataMapNode, oldId, savedId);
             }
             return;
         }
 
         String oldId = newDataMapIds.remove(map);
         if (oldId != null && !oldId.equals(savedId)) {
-            relocate(locator::dataMapNode, oldId, savedId, DATAMAP_INDEX_NODE, 
currentPath);
-        } else {
-            recordPath(locator.dataMapNode(savedId), savedId, currentPath, 
DATAMAP_INDEX_NODE);
+            relocate(locator::dataMapNode, oldId, savedId);
         }
     }
 
-    private void relocate(Function<String, Preferences> nodeForId, String 
oldId, String newId, String indexNode, String path) {
-        Preferences src = nodeForId.apply(oldId);
-        Preferences dst = nodeForId.apply(newId);
-        PreferencesCopier.move(src, dst);
-        locator.appNode(indexNode).remove(oldId);
-        recordPath(dst, newId, path, indexNode);
-    }
-
-    private void recordPath(Preferences node, String id, String path, String 
indexNode) {
-        if (path == null) {
-            return;
-        }
-        node.put(PATH_KEY, path);
-        locator.appNode(indexNode).put(id, path);
+    private static void relocate(Function<String, Preferences> nodeForId, 
String oldId, String newId) {
+        PreferencesCopier.move(nodeForId.apply(oldId), nodeForId.apply(newId));
     }
 
     private static String projectPath(Project project) {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/migration/toV5/_8_RemoveRedundantPathIndexMigration.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/migration/toV5/_8_RemoveRedundantPathIndexMigration.java
new file mode 100644
index 000000000..f6a8080b0
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/migration/toV5/_8_RemoveRedundantPathIndexMigration.java
@@ -0,0 +1,83 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.pref.migration.toV5;
+
+import org.apache.cayenne.modeler.pref.PreferenceMigration;
+import org.apache.cayenne.modeler.pref.PrefsLocator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+/**
+ * Removes the write-only {@code app/projectIndex} and {@code app/dataMapIndex}
+ * subtrees and the per-node {@code path} key from {@code project/&lt;id&gt;} /
+ * {@code datamap/&lt;id&gt;} entries. All three were introduced during the v5
+ * Modeler preferences refactor but never read by any code path; their keys
+ * fully duplicate the addressing already used by the per-project and
+ * per-DataMap subtrees.
+ */
+public class _8_RemoveRedundantPathIndexMigration implements 
PreferenceMigration {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(_8_RemoveRedundantPathIndexMigration.class);
+
+    private static final String PATH_KEY = "path";
+    private static final String PROJECT_INDEX_NODE = "projectIndex";
+    private static final String DATAMAP_INDEX_NODE = "dataMapIndex";
+    private static final String PROJECT_ROOT_NODE = "project";
+    private static final String DATAMAP_ROOT_NODE = "datamap";
+
+    @Override
+    public int version() {
+        return 8;
+    }
+
+    @Override
+    public void apply(PrefsLocator locator) {
+        removeIndexNode(locator.appNode(null), PROJECT_INDEX_NODE);
+        removeIndexNode(locator.appNode(null), DATAMAP_INDEX_NODE);
+        stripPathKey(locator.modelerRoot(), PROJECT_ROOT_NODE);
+        stripPathKey(locator.modelerRoot(), DATAMAP_ROOT_NODE);
+    }
+
+    private static void removeIndexNode(Preferences appNode, String name) {
+        try {
+            if (appNode.nodeExists(name)) {
+                appNode.node(name).removeNode();
+            }
+        } catch (BackingStoreException e) {
+            LOGGER.warn("Error removing redundant prefs index '{}'", name, e);
+        }
+    }
+
+    private static void stripPathKey(Preferences modelerRoot, String 
rootNodeName) {
+        try {
+            if (!modelerRoot.nodeExists(rootNodeName)) {
+                return;
+            }
+            Preferences root = modelerRoot.node(rootNodeName);
+            for (String childName : root.childrenNames()) {
+                root.node(childName).remove(PATH_KEY);
+            }
+        } catch (BackingStoreException e) {
+            LOGGER.warn("Error stripping '{}' from prefs under '{}'", 
PATH_KEY, rootNodeName, e);
+        }
+    }
+}
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/project/ProjectPrefs.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/project/ProjectPrefs.java
index 581d2cb3d..62ae0b397 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/project/ProjectPrefs.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/project/ProjectPrefs.java
@@ -53,7 +53,7 @@ import 
org.apache.cayenne.modeler.event.display.ProcedureDisplayEvent;
 import org.apache.cayenne.modeler.event.display.ProcedureParameterDisplayEvent;
 import org.apache.cayenne.modeler.event.display.QueryDisplayEvent;
 import org.apache.cayenne.modeler.pref.PreferenceAdapter;
-import org.apache.cayenne.modeler.pref.PrefsRepository;
+import org.apache.cayenne.modeler.pref.PrefsManager;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.util.CayenneMapEntry;
 
@@ -96,7 +96,7 @@ public final class ProjectPrefs extends PreferenceAdapter {
         query, multipleObjects
     }
 
-    public ProjectPrefs(PrefsRepository repository, Project project) {
+    public ProjectPrefs(PrefsManager repository, Project project) {
         super(repository.projectPref(project, null));
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/project/ProjectSession.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/project/ProjectSession.java
index 7d9e07ef3..8edb373fb 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/project/ProjectSession.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/project/ProjectSession.java
@@ -182,7 +182,7 @@ public class ProjectSession {
     public void projectClosed() {
 
         setDirty(false);
-        app.getPrefsRepository().resetTransientState();
+        app.getPrefsManager().resetTransientState();
 
         this.project = null;
         this.entityResolver = null;
@@ -201,14 +201,14 @@ public class ProjectSession {
         if (project == null) {
             return;
         }
-        new ProjectPrefs(app.getPrefsRepository(), project).flush(this);
+        new ProjectPrefs(app.getPrefsManager(), project).flush(this);
     }
 
     public void restoreSelectionFromPrefs() {
         if (project == null) {
             return;
         }
-        new ProjectPrefs(app.getPrefsRepository(), project).load(this);
+        new ProjectPrefs(app.getPrefsManager(), project).load(this);
     }
 
     public boolean isDirty() {
@@ -550,7 +550,7 @@ public class ProjectSession {
 
     public void fireProjectAfterSaveEvent(ProjectAfterSaveEvent e) {
         fileChangeTracker.reset();
-        app.getPrefsRepository().commitProject(project);
+        app.getPrefsManager().commitProject(project);
         for (ProjectAfterSaveListener eventListener : 
listeners.getListeners(ProjectAfterSaveListener.class)) {
             eventListener.projectSaved(e);
         }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/component/CMComponentGeometryPrefs.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/component/CMComponentGeometryPrefs.java
index d48a68dd2..f1a0119e6 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/component/CMComponentGeometryPrefs.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/component/CMComponentGeometryPrefs.java
@@ -20,7 +20,7 @@
 package org.apache.cayenne.modeler.toolkit.component;
 
 import org.apache.cayenne.modeler.pref.PreferenceAdapter;
-import org.apache.cayenne.modeler.pref.PrefsRepository;
+import org.apache.cayenne.modeler.pref.PrefsManager;
 
 import java.awt.*;
 import java.awt.event.ComponentAdapter;
@@ -33,7 +33,7 @@ public final class CMComponentGeometryPrefs extends 
PreferenceAdapter {
     private static final String X_PROPERTY = "x";
     private static final String Y_PROPERTY = "y";
 
-    public CMComponentGeometryPrefs(PrefsRepository repository, String path) {
+    public CMComponentGeometryPrefs(PrefsManager repository, String path) {
         super(repository.uiNode(path));
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/filechooser/CMFileChooserPrefs.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/filechooser/CMFileChooserPrefs.java
index b3f349736..44c8f31e4 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/filechooser/CMFileChooserPrefs.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/filechooser/CMFileChooserPrefs.java
@@ -20,7 +20,7 @@
 package org.apache.cayenne.modeler.toolkit.filechooser;
 
 import org.apache.cayenne.modeler.pref.PreferenceAdapter;
-import org.apache.cayenne.modeler.pref.PrefsRepository;
+import org.apache.cayenne.modeler.pref.PrefsManager;
 
 import javax.swing.JFileChooser;
 import java.io.File;
@@ -29,7 +29,7 @@ public final class CMFileChooserPrefs extends 
PreferenceAdapter {
 
     private static final String PATH_PROPERTY = "path";
 
-    public CMFileChooserPrefs(PrefsRepository repository, String path) {
+    public CMFileChooserPrefs(PrefsManager repository, String path) {
         super(repository.uiNode(path));
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/splitpane/CMSplitPanePrefs.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/splitpane/CMSplitPanePrefs.java
index fd2b91384..bf8e6500e 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/splitpane/CMSplitPanePrefs.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/splitpane/CMSplitPanePrefs.java
@@ -20,7 +20,7 @@
 package org.apache.cayenne.modeler.toolkit.splitpane;
 
 import org.apache.cayenne.modeler.pref.PreferenceAdapter;
-import org.apache.cayenne.modeler.pref.PrefsRepository;
+import org.apache.cayenne.modeler.pref.PrefsManager;
 
 import javax.swing.*;
 import java.beans.PropertyChangeListener;
@@ -29,7 +29,7 @@ public final class CMSplitPanePrefs extends PreferenceAdapter 
{
 
     private PropertyChangeListener listener;
 
-    public CMSplitPanePrefs(PrefsRepository repository, String path) {
+    public CMSplitPanePrefs(PrefsManager repository, String path) {
         super(repository.uiNode(path));
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMTablePrefs.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMTablePrefs.java
index 78b4a545b..99539351b 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMTablePrefs.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMTablePrefs.java
@@ -19,7 +19,7 @@
 package org.apache.cayenne.modeler.toolkit.table;
 
 import org.apache.cayenne.modeler.pref.PreferenceAdapter;
-import org.apache.cayenne.modeler.pref.PrefsRepository;
+import org.apache.cayenne.modeler.pref.PrefsManager;
 
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ListSelectionEvent;
@@ -38,8 +38,8 @@ public final class CMTablePrefs extends PreferenceAdapter {
     private static final String ORDER_KEY = "colOrder";
     private static final String LISTENER_PROPERTY = "TablePrefs.listener";
 
-    public CMTablePrefs(PrefsRepository repository, String path) {
-        super(repository.uiNode(path));
+    public CMTablePrefs(PrefsManager manager, String path) {
+        super(manager.uiNode(path));
     }
 
     /**
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/MainFrame.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/MainFrame.java
index a96536731..f0f567df1 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/MainFrame.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/MainFrame.java
@@ -114,7 +114,7 @@ public class MainFrame extends AppFrame {
         splitPane.getInsets().right = 5;
         splitPane.setResizeWeight(0.7);
 
-        this.splitPanePrefs = new CMSplitPanePrefs(app.getPrefsRepository(), 
"frame/splitPane");
+        this.splitPanePrefs = new CMSplitPanePrefs(app.getPrefsManager(), 
"frame/splitPane");
 
         JPanel statusBar = new JPanel(new FlowLayout(FlowLayout.LEFT, 3, 1));
         statusBar.setBorder(TopBorder.create());
@@ -238,7 +238,7 @@ public class MainFrame extends AppFrame {
             }
         });
 
-        new CMComponentGeometryPrefs(app.getPrefsRepository(), 
"frame/geometry").bind(this, 1200, 720);
+        new CMComponentGeometryPrefs(app.getPrefsManager(), 
"frame/geometry").bind(this, 1200, 720);
 
         setVisible(true);
     }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/DBConnectionAwareAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/DBConnectionAwareAction.java
index 237f6364e..7f6006979 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/DBConnectionAwareAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/DBConnectionAwareAction.java
@@ -73,6 +73,6 @@ public abstract class DBConnectionAwareAction extends 
AppAction {
     }
 
     private DataMapPrefs dataMapPrefs(DataMap dataMap) {
-        return new DataMapPrefs(app.getPrefsRepository(), dataMap);
+        return new DataMapPrefs(app.getPrefsManager(), dataMap);
     }
 }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/ImportDataMapAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/ImportDataMapAction.java
index 83fd71be8..78c05d88a 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/ImportDataMapAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/ImportDataMapAction.java
@@ -102,7 +102,7 @@ public class ImportDataMapAction extends AppAction {
         JFileChooser chooser = new JFileChooser();
         chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
 
-        new CMFileChooserPrefs(app.getPrefsRepository(), 
"importDataMap/lastDir").bind(chooser);
+        new CMFileChooserPrefs(app.getPrefsManager(), 
"importDataMap/lastDir").bind(chooser);
 
         chooser.addChoosableFileFilter(FileFilters.getDataMapFilter());
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/ImportEOModelAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/ImportEOModelAction.java
index 19b0dcb8c..6661dc59d 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/ImportEOModelAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/ImportEOModelAction.java
@@ -325,7 +325,7 @@ public class ImportEOModelAction extends AppAction {
             eoModelChooser = new EOModelChooser("Select EOModel");
         }
 
-        new CMFileChooserPrefs(app.getPrefsRepository(), 
"importEOModel/lastDir").bind(eoModelChooser);
+        new CMFileChooserPrefs(app.getPrefsManager(), 
"importEOModel/lastDir").bind(eoModelChooser);
 
         return eoModelChooser;
     }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/SaveAsAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/SaveAsAction.java
index 9de070a7d..437c3082f 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/SaveAsAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/SaveAsAction.java
@@ -26,7 +26,7 @@ import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.event.model.ProjectBeforeSaveEvent;
 import org.apache.cayenne.modeler.event.model.ProjectAfterSaveEvent;
-import org.apache.cayenne.modeler.pref.PrefsRepository;
+import org.apache.cayenne.modeler.pref.PrefsManager;
 import org.apache.cayenne.modeler.toolkit.AppAction;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.project.ProjectSaver;
@@ -83,7 +83,7 @@ public class SaveAsAction extends AppAction {
 
         getProjectSession().pauseFileChangeTracking();
 
-        PrefsRepository repo = app.getPrefsRepository();
+        PrefsManager repo = app.getPrefsManager();
         repo.stageProjectMove(p, projectDir);
         DataChannelDescriptor descriptor = (DataChannelDescriptor) 
p.getRootNode();
         if (descriptor != null) {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/datasource/DataSourceDialog.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/datasource/DataSourceDialog.java
index bead6be27..ac3c8d033 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/datasource/DataSourceDialog.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/datasource/DataSourceDialog.java
@@ -84,7 +84,7 @@ public class DataSourceDialog extends ProjectDialog {
         refreshDataSources();
         initFavouriteDataSource();
 
-        DataMapPrefs dataMapPrefs = new DataMapPrefs(app.getPrefsRepository(), 
session.getSelectedDataMap());
+        DataMapPrefs dataMapPrefs = new DataMapPrefs(app.getPrefsManager(), 
session.getSelectedDataMap());
         if (dataMapPrefs.hasDbAdapter()) {
             getConnectionInfoFromPreferences().copyTo(connector);
         }
@@ -163,7 +163,7 @@ public class DataSourceDialog extends ProjectDialog {
     }
 
     private DBConnector getConnectionInfoFromPreferences() {
-        DataMapPrefs dataMapPrefs = new DataMapPrefs(app.getPrefsRepository(), 
session.getSelectedDataMap());
+        DataMapPrefs dataMapPrefs = new DataMapPrefs(app.getPrefsManager(), 
session.getSelectedDataMap());
         DBConnector c = dataMapPrefs.getConnector();
         return c != null ? c : new DBConnector();
     }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbgen/DBGeneratorOptionsDialog.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbgen/DBGeneratorOptionsDialog.java
index 4204a5642..ba1795912 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbgen/DBGeneratorOptionsDialog.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbgen/DBGeneratorOptionsDialog.java
@@ -106,7 +106,7 @@ public class DBGeneratorOptionsDialog extends ProjectDialog 
{
 
         this.connector = new DBConnector();
         this.connector.setAllowDataSourceFailure(true);
-        this.generatorDefaults = new 
DBGeneratorPrefs(app.getPrefsRepository(), session.project());
+        this.generatorDefaults = new DBGeneratorPrefs(app.getPrefsManager(), 
session.project());
 
         // create widgets — set initial state before wiring listeners so we
         // don't fire spurious refresh events during construction.
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbgen/DBGeneratorPrefs.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbgen/DBGeneratorPrefs.java
index 17a436d72..23b5e8aee 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbgen/DBGeneratorPrefs.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbgen/DBGeneratorPrefs.java
@@ -19,7 +19,7 @@
 package org.apache.cayenne.modeler.ui.dbgen;
 
 import org.apache.cayenne.modeler.pref.PreferenceAdapter;
-import org.apache.cayenne.modeler.pref.PrefsRepository;
+import org.apache.cayenne.modeler.pref.PrefsManager;
 import org.apache.cayenne.project.Project;
 
 /**
@@ -35,7 +35,7 @@ public class DBGeneratorPrefs extends PreferenceAdapter {
     private static final String DROP_PK_PROPERTY = "dropPK";
     private static final String DROP_TABLES_PROPERTY = "dropTables";
 
-    public DBGeneratorPrefs(PrefsRepository repository, Project project) {
+    public DBGeneratorPrefs(PrefsManager repository, Project project) {
         super(repository.projectPref(project, NODE));
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
index 5384c1ef6..cd050ed2c 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
@@ -321,7 +321,7 @@ public class DbRelationshipDialog extends ProjectDialog {
         AutoCompletion.enable(targetCombo, session::getSelectedDataMap);
         targetColumn.setCellEditor(new CMComboBoxCellEditor(targetCombo));
 
-        new CMTablePrefs(app.getPrefsRepository(), "dbEntity/dbjoinTable")
+        new CMTablePrefs(app.getPrefsManager(), "dbEntity/dbjoinTable")
                 .bind(table, null, DbJoinTableModel.SOURCE);
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/preferences/classpath/ClasspathPrefsPanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/preferences/classpath/ClasspathPrefsPanel.java
index 27ad31874..0bd87c22b 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/preferences/classpath/ClasspathPrefsPanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/preferences/classpath/ClasspathPrefsPanel.java
@@ -139,7 +139,7 @@ public class ClasspathPrefsPanel extends AppPanel {
         chooser.setDialogType(JFileChooser.OPEN_DIALOG);
         chooser.setAcceptAllFileFilterUsed(true);
 
-        new CMFileChooserPrefs(app.getPrefsRepository(), 
"classpath/lastDir").bind(chooser);
+        new CMFileChooserPrefs(app.getPrefsManager(), 
"classpath/lastDir").bind(chooser);
         if (filter != null) {
             chooser.addChoosableFileFilter(filter);
             chooser.setFileFilter(filter);
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/preferences/more/MorePrefsPanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/preferences/more/MorePrefsPanel.java
index eef56edf9..bb042c282 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/preferences/more/MorePrefsPanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/preferences/more/MorePrefsPanel.java
@@ -111,7 +111,7 @@ public class MorePrefsPanel extends AppPanel {
         }
         app.getFrame().dispose();
 
-        app.getPrefsRepository().resetToDefaults(importLegacy);
+        app.getPrefsManager().resetToDefaults(importLegacy);
 
         // Defer the rebuild to a later EDT tick so the in-flight action 
handler
         // (and any pending dispose events) drain first.
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/ProjectView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/ProjectView.java
index 7d27ae244..21de66b6e 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/ProjectView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/ProjectView.java
@@ -102,7 +102,7 @@ public class ProjectView extends ProjectPanel {
 
         this.filterPopup = new TreeFilterPopup(treePanel);
 
-        new CMSplitPanePrefs(app.getPrefsRepository(), 
"project/splitPane").bind(splitPane, 300);
+        new CMSplitPanePrefs(app.getPrefsManager(), 
"project/splitPane").bind(splitPane, 300);
     }
 
     public EditorPanelView getEditorPanel() {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datadomain/main/DataDomainMainView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datadomain/main/DataDomainMainView.java
index e0808270f..38c0fbbdd 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datadomain/main/DataDomainMainView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datadomain/main/DataDomainMainView.java
@@ -203,7 +203,7 @@ public class DataDomainMainView extends ProjectPanel 
implements DomainDisplayLis
                 this,
                 dataChannelDescriptor,
                 dataChannelDescriptor.getName());
-        app.getPrefsRepository().stageProjectRename(session.project(), 
newName);
+        app.getPrefsManager().stageProjectRename(session.project(), newName);
         dataChannelDescriptor.setName(newName);
 
         session.fireDomainEvent(e);
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/cgen/templateeditor/TemplateEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/cgen/templateeditor/TemplateEditor.java
index befe628c9..d131578a2 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/cgen/templateeditor/TemplateEditor.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/cgen/templateeditor/TemplateEditor.java
@@ -256,8 +256,8 @@ public class TemplateEditor extends AppFrame {
     }
 
     private void bindGeometry() {
-        new CMSplitPanePrefs(app.getPrefsRepository(), 
"templateEditor/splitPane").bind(split, 600);
-        new CMComponentGeometryPrefs(app.getPrefsRepository(), 
"templateEditor/geometry").bind(this, 1200, 700);
+        new CMSplitPanePrefs(app.getPrefsManager(), 
"templateEditor/splitPane").bind(split, 600);
+        new CMComponentGeometryPrefs(app.getPrefsManager(), 
"templateEditor/geometry").bind(this, 1200, 700);
     }
 
     private void mapVelocityTokenMaker() {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/main/DataMapMainView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/main/DataMapMainView.java
index f204586eb..adc918264 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/main/DataMapMainView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/main/DataMapMainView.java
@@ -241,7 +241,7 @@ public class DataMapMainView extends ProjectPanel {
         dataMap.setDefaultPackage(newDefaultPackage);
 
         // update class generation preferences
-        new DataMapPrefs(app.getPrefsRepository(), dataMap)
+        new DataMapPrefs(app.getPrefsManager(), dataMap)
                 .setSuperclassPackage(newDefaultPackage, 
DataMapPrefs.DEFAULT_SUPERCLASS_PACKAGE_SUFFIX);
 
         session.fireDataMapEvent(DataMapEvent.ofChange(this, dataMap));
@@ -343,7 +343,7 @@ public class DataMapMainView extends ProjectPanel {
                 nodesUsingMap.add(node);
             }
         }
-        app.getPrefsRepository().stageDataMapRename(map, newName);
+        app.getPrefsManager().stageDataMapRename(map, newName);
         map.setName(newName);
         for (DataNodeDescriptor node : nodesUsingMap) {
             node.getDataMapNames().remove(oldName);
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datanode/DataNodeEditorPanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datanode/DataNodeEditorPanel.java
index cfaf3d569..b98165e5a 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datanode/DataNodeEditorPanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datanode/DataNodeEditorPanel.java
@@ -231,7 +231,7 @@ public class DataNodeEditorPanel extends ProjectPanel {
         String oldName = node.getName();
         node.setName(newName);
 
-        new DataNodePrefs(app.getPrefsRepository(), session.project(), 
oldName).rename(newName);
+        new DataNodePrefs(app.getPrefsManager(), session.project(), 
oldName).rename(newName);
     }
 
     private DataNodePrefs nodePrefs() {
@@ -239,7 +239,7 @@ public class DataNodeEditorPanel extends ProjectPanel {
         if (selected == null) {
             throw new IllegalStateException("No DataNode selected");
         }
-        return new DataNodePrefs(app.getPrefsRepository(), session.project(), 
selected.getName());
+        return new DataNodePrefs(app.getPrefsManager(), session.project(), 
selected.getName());
     }
 
     private void dataSourceConfigAction() {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datanode/jdbc/JDBCDataSourcePanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datanode/jdbc/JDBCDataSourcePanel.java
index c38552fcb..ca798c59e 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datanode/jdbc/JDBCDataSourcePanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datanode/jdbc/JDBCDataSourcePanel.java
@@ -159,7 +159,7 @@ public class JDBCDataSourcePanel extends DataSourcePanel {
         DataSourceDescriptor projectDataSourceDescriptor = 
getNode().getDataSourceDescriptor();
 
         String key = new DataNodePrefs(
-                app.getPrefsRepository(),
+                app.getPrefsManager(),
                 frame.getProjectSession().project(),
                 getNode().getName()).getLocalDataSource();
         if (key == null) {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbAttributePanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbAttributePanel.java
index 38c815c0d..33751d06c 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbAttributePanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbAttributePanel.java
@@ -185,7 +185,7 @@ public class DbAttributePanel extends JPanel implements 
DbEntityDisplayListener,
         TableColumn typeColumn = 
table.getColumnModel().getColumn(DbAttributeTableModel.DB_ATTRIBUTE_TYPE);
         typeColumn.setCellEditor(new CMComboBoxCellEditor(comboBox));
 
-        new CMTablePrefs(session.app().getPrefsRepository(), 
"dbEntity/attributeTable")
+        new CMTablePrefs(session.app().getPrefsManager(), 
"dbEntity/attributeTable")
                 .bind(table, null, DbAttributeTableModel.DB_ATTRIBUTE_NAME);
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbEntityPropertiesView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbEntityPropertiesView.java
index d562470f2..68806b65b 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbEntityPropertiesView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbEntityPropertiesView.java
@@ -71,7 +71,7 @@ public class DbEntityPropertiesView extends ProjectPanel 
implements DbEntityDisp
 
         splitPane.setOneTouchExpandable(true);
         splitPane.setResizeWeight(0.5);
-        new CMSplitPanePrefs(app.getPrefsRepository(), 
"dbEntity/splitPane").bind(splitPane, -1);
+        new CMSplitPanePrefs(app.getPrefsManager(), 
"dbEntity/splitPane").bind(splitPane, -1);
         add(splitPane);
 
         toolBar.setFloatable(false);
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbRelationshipPanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbRelationshipPanel.java
index 555022f72..5f51566c9 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbRelationshipPanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbRelationshipPanel.java
@@ -193,7 +193,7 @@ public class DbRelationshipPanel extends JPanel implements 
DbEntityDisplayListen
         TableColumn toDepPkColumn = 
table.getColumnModel().getColumn(DbRelationshipTableModel.TO_DEPENDENT_KEY);
         toDepPkColumn.setCellRenderer(new CheckBoxCellRenderer());
 
-        new CMTablePrefs(session.app().getPrefsRepository(), 
"dbEntity/relationshipTable")
+        new CMTablePrefs(session.app().getPrefsManager(), 
"dbEntity/relationshipTable")
                 .bind(table, null, DbRelationshipTableModel.NAME);
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/embeddable/attributes/EmbeddableAttributesView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/embeddable/attributes/EmbeddableAttributesView.java
index a47638c6a..b9d1036be 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/embeddable/attributes/EmbeddableAttributesView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/embeddable/attributes/EmbeddableAttributesView.java
@@ -171,7 +171,7 @@ public class EmbeddableAttributesView extends ProjectPanel 
implements
         AutoCompletion.enable(javaTypesCombo, false, true, 
session::getSelectedDataMap);
         typeColumn.setCellEditor(new CMComboBoxCellEditor(javaTypesCombo));
 
-        new CMTablePrefs(app.getPrefsRepository(), "embeddable/attributeTable")
+        new CMTablePrefs(app.getPrefsManager(), "embeddable/attributeTable")
                 .bind(table, null, 
EmbeddableAttributeTableModel.OBJ_ATTRIBUTE);
 
     }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/attrinfo/ObjAttributeInfoDialog.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/attrinfo/ObjAttributeInfoDialog.java
index 55f3f1850..a11b3e699 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/attrinfo/ObjAttributeInfoDialog.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/attrinfo/ObjAttributeInfoDialog.java
@@ -411,7 +411,7 @@ public class ObjAttributeInfoDialog extends ProjectDialog 
implements TreeSelecti
                 
.getColumn(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE_TYPE);
         dbAttrTypeColumn.setCellRenderer(renderer);
 
-        new CMTablePrefs(app.getPrefsRepository(), 
"objEntity/overrideAttributeTable")
+        new CMTablePrefs(app.getPrefsManager(), 
"objEntity/overrideAttributeTable")
                 .bind(overrideAttributeTable, null,
                         OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE);
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/callbacks/ObjEntityCallbacksView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/callbacks/ObjEntityCallbacksView.java
index 7cd8ba9d8..99592211e 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/callbacks/ObjEntityCallbacksView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/callbacks/ObjEntityCallbacksView.java
@@ -219,7 +219,7 @@ public class ObjEntityCallbacksView extends ProjectPanel {
         }
 
         for (CMTable table : tables) {
-            new CMTablePrefs(app.getPrefsRepository(), 
"objEntity/callbackTable")
+            new CMTablePrefs(app.getPrefsManager(), "objEntity/callbackTable")
                     .bind(table, MIN_SIZES);
         }
     }
@@ -513,7 +513,7 @@ public class ObjEntityCallbacksView extends ProjectPanel {
 
         public void mouseDragged(MouseEvent e) {
             if (table.getColumnWidthChanged()) {
-                new CMTablePrefs(app.getPrefsRepository(), 
"objEntity/callbackTable")
+                new CMTablePrefs(app.getPrefsManager(), 
"objEntity/callbackTable")
                         .bind(table, MIN_SIZES);
                 for (CMTable nextTable : tables) {
                     if (!table.equals(nextTable)) {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjAttributePanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjAttributePanel.java
index e3d61c040..3f8c430d7 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjAttributePanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjAttributePanel.java
@@ -318,7 +318,7 @@ public class ObjAttributePanel extends JPanel implements 
ObjEntityDisplayListene
         
table.getColumnModel().getColumn(ObjAttributeTableModel.DB_ATTRIBUTE).setCellRenderer(new
 DbAttributePathComboBoxRenderer());
         
table.getColumnModel().getColumn(ObjAttributeTableModel.DB_ATTRIBUTE).setCellEditor(new
 DbAttributePathComboBoxEditor(session::getSelectedDataMap));
 
-        new CMTablePrefs(session.app().getPrefsRepository(), 
"objEntity/attributeTable")
+        new CMTablePrefs(session.app().getPrefsManager(), 
"objEntity/attributeTable")
                 .bind(table, minSizes, ObjAttributeTableModel.OBJ_ATTRIBUTE);
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjEntityPropertiesView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjEntityPropertiesView.java
index 45937608d..93637d37e 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjEntityPropertiesView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjEntityPropertiesView.java
@@ -67,7 +67,7 @@ public class ObjEntityPropertiesView extends ProjectPanel 
implements ObjEntityDi
 
         splitPane.setOneTouchExpandable(true);
         splitPane.setResizeWeight(0.5);
-        new CMSplitPanePrefs(app.getPrefsRepository(), 
"objEntity/splitPane").bind(splitPane, -1);
+        new CMSplitPanePrefs(app.getPrefsManager(), 
"objEntity/splitPane").bind(splitPane, -1);
         add(splitPane);
 
         toolBar.setFloatable(false);
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
index e224efe5e..fbd4c7a5b 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
@@ -276,7 +276,7 @@ public class ObjRelationshipPanel extends JPanel implements 
ObjEntityDisplayList
         deleteRulesCombo.setSelectedIndex(0); // Default to the first value
         col.setCellEditor(new CMComboBoxCellEditor(deleteRulesCombo));
 
-        new CMTablePrefs(session.app().getPrefsRepository(), 
"objEntity/relationshipTable")
+        new CMTablePrefs(session.app().getPrefsManager(), 
"objEntity/relationshipTable")
                 .bind(table, null, ObjRelationshipTableModel.REL_NAME);
     }
 
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureParameterTab.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureParameterTab.java
index 6422d91a7..ced3323fc 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureParameterTab.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureParameterTab.java
@@ -287,7 +287,7 @@ public class ProcedureParameterTab extends ProjectPanel 
implements ProcedurePara
         moveUp.setEnabled(false);
         moveDown.setEnabled(false);
 
-        new CMTablePrefs(app.getPrefsRepository(), 
"procedure/parameterTable").bind(table, null);
+        new CMTablePrefs(app.getPrefsManager(), 
"procedure/parameterTable").bind(table, null);
     }
 
     public void procedureParameterAdded(ProcedureParameterEvent e) {
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/selectquery/SelectQueryOrderingTab.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/selectquery/SelectQueryOrderingTab.java
index e836bbd3c..18973568b 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/selectquery/SelectQueryOrderingTab.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/selectquery/SelectQueryOrderingTab.java
@@ -81,7 +81,7 @@ public class SelectQueryOrderingTab extends ProjectPanel {
 
         //As of CAY-888 #3 main pane is now a JSplitPane. Top component is a 
bit larger.
         JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-        new CMSplitPanePrefs(app.getPrefsRepository(), 
"selectQuery/orderingSplit").bind(mainPanel, defLocation);
+        new CMSplitPanePrefs(app.getPrefsManager(), 
"selectQuery/orderingSplit").bind(mainPanel, defLocation);
 
         mainPanel.setTopComponent(createEditorPanel());
         mainPanel.setBottomComponent(createSelectorPanel());
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/sqltemplate/SQLTemplatePrefetchTab.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/sqltemplate/SQLTemplatePrefetchTab.java
index 0f4afabbb..e27f0ba20 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/sqltemplate/SQLTemplatePrefetchTab.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/sqltemplate/SQLTemplatePrefetchTab.java
@@ -92,7 +92,7 @@ public class SQLTemplatePrefetchTab extends ProjectPanel {
 
         //As of CAY-888 #3 main pane is now a JSplitPane. Top component is a 
bit larger.
         JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-        new CMSplitPanePrefs(app.getPrefsRepository(), 
"sqlTemplate/prefetchSplit").bind(mainPanel, defLocation);
+        new CMSplitPanePrefs(app.getPrefsManager(), 
"sqlTemplate/prefetchSplit").bind(mainPanel, defLocation);
 
         mainPanel.setTopComponent(createEditorPanel());
         mainPanel.setBottomComponent(createSelectorPanel());
diff --git 
a/modeler/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/pref/migration/toV5/_8_RemoveRedundantPathIndexMigrationTest.java
 
b/modeler/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/pref/migration/toV5/_8_RemoveRedundantPathIndexMigrationTest.java
new file mode 100644
index 000000000..185a19f73
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/pref/migration/toV5/_8_RemoveRedundantPathIndexMigrationTest.java
@@ -0,0 +1,94 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.pref.migration.toV5;
+
+import org.apache.cayenne.modeler.pref.PrefsLocator;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.UUID;
+import java.util.prefs.Preferences;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+public class _8_RemoveRedundantPathIndexMigrationTest {
+
+    private Preferences testRoot;
+    private PrefsLocator locator;
+
+    @BeforeEach
+    public void setUp() {
+        testRoot = Preferences.userRoot().node("test-cayenne-prefs-" + 
UUID.randomUUID());
+        locator = new PrefsLocator(testRoot);
+    }
+
+    @AfterEach
+    public void tearDown() throws Exception {
+        testRoot.removeNode();
+    }
+
+    @Test
+    public void removesIndexSubtreesAndPathKeys() throws Exception {
+        Preferences app = locator.appNode(null);
+        app.node("projectIndex").put("abc-cayenne-project", 
"/tmp/cayenne-project.xml");
+        app.node("dataMapIndex").put("def-datamap", "/tmp/datamap.map.xml");
+
+        Preferences projectEntry = locator.projectNode("abc-cayenne-project");
+        projectEntry.put("path", "/tmp/cayenne-project.xml");
+        projectEntry.put("domain", "project");
+
+        Preferences dataMapEntry = locator.dataMapNode("def-datamap");
+        dataMapEntry.put("path", "/tmp/datamap.map.xml");
+        dataMapEntry.put("superclassPackage", "org.example");
+
+        app.flush();
+
+        new _8_RemoveRedundantPathIndexMigration().apply(locator);
+
+        assertFalse(app.nodeExists("projectIndex"),
+                "projectIndex subtree should be removed");
+        assertFalse(app.nodeExists("dataMapIndex"),
+                "dataMapIndex subtree should be removed");
+
+        assertNull(projectEntry.get("path", null),
+                "path key on project node should be removed");
+        assertEquals("project", projectEntry.get("domain", null),
+                "unrelated project node keys should survive");
+
+        assertNull(dataMapEntry.get("path", null),
+                "path key on datamap node should be removed");
+        assertEquals("org.example", dataMapEntry.get("superclassPackage", 
null),
+                "unrelated datamap node keys should survive");
+    }
+
+    @Test
+    public void isIdempotentOnEmptyTree() {
+        new _8_RemoveRedundantPathIndexMigration().apply(locator);
+        new _8_RemoveRedundantPathIndexMigration().apply(locator);
+    }
+
+    @Test
+    public void version() {
+        assertEquals(8, new _8_RemoveRedundantPathIndexMigration().version());
+    }
+}

Reply via email to