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
The following commit(s) were added to refs/heads/master by this push:
new 0562b108d Modeler prefs to handle project and DataMap renaming
0562b108d is described below
commit 0562b108d1f974831fe2233ff10f0c52dae2147d
Author: Andrus Adamchik <[email protected]>
AuthorDate: Wed May 6 15:09:06 2026 -0400
Modeler prefs to handle project and DataMap renaming
---
.../cayenne/modeler/pref/PreferenceNodeIds.java | 2 +-
.../modeler/pref/PreferencesJsonExporter.java | 126 ++++++++++
.../modeler/pref/PreferencesRepository.java | 267 ++++++++++-----------
.../cayenne/modeler/project/ProjectSession.java | 1 +
.../cayenne/modeler/ui/action/SaveAsAction.java | 12 +
.../editor/datadomain/main/DataDomainMainView.java | 1 +
.../editor/datamap/main/DataMapMainView.java | 1 +
7 files changed, 273 insertions(+), 137 deletions(-)
diff --git
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferenceNodeIds.java
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferenceNodeIds.java
index 7da335c4e..fef18c281 100644
---
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferenceNodeIds.java
+++
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferenceNodeIds.java
@@ -30,7 +30,7 @@ import java.util.prefs.Preferences;
* characters, well below {@link Preferences#MAX_NAME_LENGTH}. The original
absolute
* path is meant to be stored alongside the node as a {@code path} value.
*/
-final class PreferenceNodeIds {
+class PreferenceNodeIds {
static final int MAX_LEN = 60;
static final int HASH_LEN = 16;
diff --git
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferencesJsonExporter.java
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferencesJsonExporter.java
new file mode 100644
index 000000000..9091ce47a
--- /dev/null
+++
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferencesJsonExporter.java
@@ -0,0 +1,126 @@
+/*****************************************************************
+ * 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;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+class PreferencesJsonExporter {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(PreferencesJsonExporter.class);
+
+ public static String exportAsJson(Preferences node) {
+ StringBuilder sb = new StringBuilder();
+ appendNode(sb, node, 0);
+ return sb.toString();
+ }
+
+ private static void appendNode(StringBuilder sb, Preferences node, int
indent) {
+ String[] keys;
+ String[] children;
+ try {
+ keys = node.keys();
+ children = node.childrenNames();
+ } catch (BackingStoreException e) {
+ LOGGER.warn("Error reading preferences node '{}'",
node.absolutePath(), e);
+ sb.append("{}");
+ return;
+ }
+
+ if (keys.length == 0 && children.length == 0) {
+ sb.append("{}");
+ return;
+ }
+
+ Arrays.sort(keys);
+ Arrays.sort(children);
+
+ sb.append("{\n");
+ boolean first = true;
+ for (String key : keys) {
+ if (!first) {
+ sb.append(",\n");
+ }
+ indent(sb, indent + 1);
+ appendString(sb, key);
+ sb.append(": ");
+ appendString(sb, node.get(key, ""));
+ first = false;
+ }
+ for (String childName : children) {
+ if (!first) {
+ sb.append(",\n");
+ }
+ indent(sb, indent + 1);
+ appendString(sb, childName);
+ sb.append(": ");
+ appendNode(sb, node.node(childName), indent + 1);
+ first = false;
+ }
+ sb.append('\n');
+ indent(sb, indent);
+ sb.append('}');
+ }
+
+ private static void appendString(StringBuilder sb, String s) {
+ sb.append('"');
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '"':
+ sb.append("\\\"");
+ break;
+ case '\\':
+ sb.append("\\\\");
+ break;
+ case '\n':
+ sb.append("\\n");
+ break;
+ case '\r':
+ sb.append("\\r");
+ break;
+ case '\t':
+ sb.append("\\t");
+ break;
+ case '\b':
+ sb.append("\\b");
+ break;
+ case '\f':
+ sb.append("\\f");
+ break;
+ default:
+ if (c < 0x20) {
+ sb.append(String.format("\\u%04x", (int) c));
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ sb.append('"');
+ }
+
+ private static void indent(StringBuilder sb, int level) {
+ sb.append(" ".repeat(Math.max(0, level)));
+ }
+}
diff --git
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferencesRepository.java
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferencesRepository.java
index 2a1530e78..984aa9413 100644
---
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferencesRepository.java
+++
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/PreferencesRepository.java
@@ -19,6 +19,7 @@
package org.apache.cayenne.modeler.pref;
import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.di.Inject;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.modeler.pref.migration.toV5._1_DbConnectorsMigration;
import org.apache.cayenne.modeler.pref.migration.toV5._2_ClasspathMigration;
@@ -27,13 +28,15 @@ 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.configuration.ConfigurationNameMapper;
import org.apache.cayenne.project.Project;
import org.apache.cayenne.resource.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Arrays;
+import java.io.File;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
@@ -42,6 +45,7 @@ import java.util.prefs.Preferences;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+
/**
* App-wide preferences service for the Modeler. Owns the layout under
* {@code org/apache/cayenne/modeler/v5} and resolves project / DataMap nodes
@@ -67,11 +71,15 @@ public class PreferencesRepository {
static final String PATH_KEY = "path";
static final String UNSAVED_PREFIX = "unsaved-";
- private final Preferences root;
- private final Map<Project, String> unsavedProjectIds;
- private final Map<DataMap, String> unsavedDataMapIds;
+ private final ConfigurationNameMapper nameMapper;
private final List<PreferenceMigration> migrations;
+ private final Preferences root;
+ private final Map<Project, String> newProjectIds;
+ private final Map<DataMap, String> newDataMapIds;
+ private final Map<String, String> stagingDataMap;
+ private final Map<String, String> stagingProject;
+
private static List<PreferenceMigration> toV5Migrations() {
return Stream.of(
new _1_DbConnectorsMigration(),
@@ -87,11 +95,14 @@ public class PreferencesRepository {
.collect(Collectors.toList());
}
- public PreferencesRepository() {
+ public PreferencesRepository(@Inject ConfigurationNameMapper nameMapper) {
+ this.nameMapper = nameMapper;
this.root = Preferences.userRoot().node(ROOT_PATH);
this.migrations = toV5Migrations();
- this.unsavedProjectIds = new IdentityHashMap<>();
- this.unsavedDataMapIds = new IdentityHashMap<>();
+ this.newProjectIds = new IdentityHashMap<>();
+ this.newDataMapIds = new IdentityHashMap<>();
+ this.stagingDataMap = new HashMap<>();
+ this.stagingProject = new HashMap<>();
}
public Preferences appPref(String relativePath) {
@@ -110,12 +121,7 @@ public class PreferencesRepository {
}
/**
- * Returns the preferences node for the given {@link Project}, optionally
- * descending into a {@code relativePath} sub-tree within it. If the
project
- * has been saved to disk, the project's subtree is keyed by a stable hash
- * of its configuration file path; otherwise by a per-runtime
- * {@code unsaved-<ts>} id assigned on first lookup. Pass {@code null} or
- * an empty {@code relativePath} to get the project base node itself.
+ * Returns the preferences node for the given {@link Project}, optionally
descending into a subtree within it.
*/
public Preferences projectPref(Project project, String relativePath) {
String id = projectId(project);
@@ -125,12 +131,7 @@ public class PreferencesRepository {
}
/**
- * Returns the preferences node for the given {@link DataMap}, optionally
- * descending into a {@code relativePath} sub-tree within it. Like
- * {@link #projectPref(Project, String)}, the DataMap's subtree is keyed by
- * file path when saved or by a {@code unsaved-<ts>} id otherwise. Pass
- * {@code null} or an empty {@code relativePath} to get the DataMap base
- * node itself.
+ * Returns the preferences node for the given {@link DataMap}, optionally
descending into a subtree within it.
*/
public Preferences dataMapPref(DataMap map, String relativePath) {
String id = dataMapId(map);
@@ -141,27 +142,20 @@ public class PreferencesRepository {
private String projectId(Project project) {
String path = projectPath(project);
- if (path != null) {
- return PreferenceNodeIds.idForPath(path);
- }
- return unsavedProjectIds.computeIfAbsent(project, p -> newUnsavedId());
+ return path != null
+ ? PreferenceNodeIds.idForPath(path)
+ : newProjectIds.computeIfAbsent(project, p -> newUnsavedId());
}
private String dataMapId(DataMap map) {
String path = dataMapPath(map);
- if (path != null) {
- return PreferenceNodeIds.idForPath(path);
- }
- return unsavedDataMapIds.computeIfAbsent(map, m -> newUnsavedId());
+ return path != null
+ ? PreferenceNodeIds.idForPath(path)
+ : newDataMapIds.computeIfAbsent(map, m -> newUnsavedId());
}
/**
- * Reconciles preferences after a project save. For the project and every
- * DataMap, if the current file-path-derived id differs from where its
- * preferences subtree currently lives (an unsaved id, or a different saved
- * id from a previous Save As), copies the subtree to the new id and
removes
- * the old. Updates the {@code projectIndex} / {@code dataMapIndex}
- * reverse-lookup nodes. Idempotent.
+ * Reconciles preferences after a project save.
*/
public void commitProject(Project project) {
if (project == null) {
@@ -175,6 +169,76 @@ public class PreferencesRepository {
reconcileDataMap(map);
}
}
+
+ resetTransientState();
+ }
+
+ /**
+ * Records a pending DataMap rename so that {@link
#commitProject(Project)} can migrate
+ * the DataMap's preferences subtree from the old node to the new one.
+ */
+ public void stageDataMapRename(DataMap map, String newName) {
+ String oldPath = dataMapPath(map);
+ if (oldPath == null) {
+ return;
+ }
+ int slash = oldPath.lastIndexOf('/');
+ String dir = slash >= 0 ? oldPath.substring(0, slash + 1) : "";
+ String newPath = dir + nameMapper.configurationLocation(DataMap.class,
newName);
+ stagingDataMap.put(PreferenceNodeIds.idForPath(newPath), oldPath);
+ }
+
+ /**
+ * Records a pending project rename (domain name change) so that {@link
#commitProject(Project)} can migrate project
+ * preferences from the old node to the new one.
+ */
+ public void stageProjectRename(Project project, String newDomainName) {
+ String oldPath = projectPath(project);
+ if (oldPath == null) {
+ return;
+ }
+ int slash = oldPath.lastIndexOf('/');
+ String dir = slash >= 0 ? oldPath.substring(0, slash + 1) : "";
+ String newPath = dir +
nameMapper.configurationLocation(DataChannelDescriptor.class, newDomainName);
+ stagingProject.put(PreferenceNodeIds.idForPath(newPath), oldPath);
+ }
+
+ /**
+ * Records a pending DataMap move (project Save As) so that preferences
are carried to
+ * the new location. Must be called before the save writes updated paths
to disk.
+ */
+ public void stageDataMapMove(DataMap map, File newProjectDir) {
+ String oldPath = dataMapPath(map);
+ if (oldPath == null) {
+ return;
+ }
+ String newPath = new File(newProjectDir,
nameMapper.configurationLocation(DataMap.class, map.getName())).getPath();
+ stagingDataMap.put(PreferenceNodeIds.idForPath(newPath), oldPath);
+ }
+
+ /**
+ * Records a pending project move (Save As) so that project-level
preferences are
+ * carried to the new location. Must be called before the save writes
updated paths.
+ */
+ public void stageProjectMove(Project project, File newProjectDir) {
+ String oldPath = projectPath(project);
+ if (oldPath == null) {
+ return;
+ }
+ String fileName = new File(oldPath).getName();
+ String newPath = new File(newProjectDir, fileName).getPath();
+ stagingProject.put(PreferenceNodeIds.idForPath(newPath), oldPath);
+ }
+
+ /**
+ * Resets all transient per-project state: in-memory unsaved-id
bookkeeping and
+ * persisted staging records. Call on both project open and project close.
+ */
+ public void resetTransientState() {
+ newProjectIds.clear();
+ newDataMapIds.clear();
+ stagingDataMap.clear();
+ stagingProject.clear();
}
/**
@@ -184,9 +248,7 @@ public class PreferencesRepository {
* to nested objects.
*/
public String exportAsJson() {
- StringBuilder sb = new StringBuilder();
- appendNode(sb, root, 0);
- return sb.toString();
+ return PreferencesJsonExporter.exportAsJson(root);
}
/**
@@ -214,8 +276,8 @@ public class PreferencesRepository {
} catch (BackingStoreException e) {
LOGGER.warn("Error deleting all preferences under '{}'",
root.absolutePath(), e);
}
- unsavedProjectIds.clear();
- unsavedDataMapIds.clear();
+ newProjectIds.clear();
+ newDataMapIds.clear();
if (!importLegacyPreferences && !migrations.isEmpty()) {
int highest = migrations.get(migrations.size() - 1).version();
@@ -260,7 +322,19 @@ public class PreferencesRepository {
return;
}
String savedId = PreferenceNodeIds.idForPath(currentPath);
- String oldId = unsavedProjectIds.remove(project);
+
+ String stagedOldPath = stagingProject.get(savedId);
+ if (stagedOldPath != null) {
+ String oldId = PreferenceNodeIds.idForPath(stagedOldPath);
+ if (!oldId.equals(savedId)) {
+ relocate(PROJECT_NODE, oldId, savedId, PROJECT_INDEX_NODE,
currentPath);
+ } else {
+ recordPath(root.node(PROJECT_NODE).node(savedId), currentPath,
PROJECT_INDEX_NODE, savedId);
+ }
+ return;
+ }
+
+ String oldId = newProjectIds.remove(project);
if (oldId != null && !oldId.equals(savedId)) {
relocate(PROJECT_NODE, oldId, savedId, PROJECT_INDEX_NODE,
currentPath);
} else {
@@ -274,7 +348,19 @@ public class PreferencesRepository {
return;
}
String savedId = PreferenceNodeIds.idForPath(currentPath);
- String oldId = unsavedDataMapIds.remove(map);
+
+ String stagedOldPath = stagingDataMap.get(savedId);
+ if (stagedOldPath != null) {
+ String oldId = PreferenceNodeIds.idForPath(stagedOldPath);
+ if (!oldId.equals(savedId)) {
+ relocate(DATAMAP_NODE, oldId, savedId, DATAMAP_INDEX_NODE,
currentPath);
+ } else {
+ recordPath(root.node(DATAMAP_NODE).node(savedId), currentPath,
DATAMAP_INDEX_NODE, savedId);
+ }
+ return;
+ }
+
+ String oldId = newDataMapIds.remove(map);
if (oldId != null && !oldId.equals(savedId)) {
relocate(DATAMAP_NODE, oldId, savedId, DATAMAP_INDEX_NODE,
currentPath);
} else {
@@ -286,6 +372,7 @@ public class PreferencesRepository {
Preferences src = root.node(parentNode).node(oldId);
Preferences dst = root.node(parentNode).node(newId);
PreferencesCopier.move(src, dst);
+ appPref(indexNode).remove(oldId);
recordPath(dst, path, indexNode, newId);
}
@@ -301,113 +388,21 @@ public class PreferencesRepository {
if (project == null) {
return null;
}
+
Resource resource = project.getConfigurationResource();
- if (resource == null) {
- return null;
- }
- return resource.getURL().getPath();
+ return resource == null ? null : resource.getURL().getPath();
}
private static String dataMapPath(DataMap map) {
if (map == null) {
return null;
}
+
Resource resource = map.getConfigurationSource();
- if (resource == null) {
- return null;
- }
- return resource.getURL().getPath();
+ return resource == null ? null : resource.getURL().getPath();
}
private static String newUnsavedId() {
return UNSAVED_PREFIX + System.currentTimeMillis() + "-" +
System.nanoTime();
}
-
- private static void appendNode(StringBuilder sb, Preferences node, int
indent) {
- String[] keys;
- String[] children;
- try {
- keys = node.keys();
- children = node.childrenNames();
- } catch (BackingStoreException e) {
- LOGGER.warn("Error reading preferences node '{}'",
node.absolutePath(), e);
- sb.append("{}");
- return;
- }
-
- if (keys.length == 0 && children.length == 0) {
- sb.append("{}");
- return;
- }
-
- Arrays.sort(keys);
- Arrays.sort(children);
-
- sb.append("{\n");
- boolean first = true;
- for (String key : keys) {
- if (!first) {
- sb.append(",\n");
- }
- indent(sb, indent + 1);
- appendString(sb, key);
- sb.append(": ");
- appendString(sb, node.get(key, ""));
- first = false;
- }
- for (String childName : children) {
- if (!first) {
- sb.append(",\n");
- }
- indent(sb, indent + 1);
- appendString(sb, childName);
- sb.append(": ");
- appendNode(sb, node.node(childName), indent + 1);
- first = false;
- }
- sb.append('\n');
- indent(sb, indent);
- sb.append('}');
- }
-
- private static void appendString(StringBuilder sb, String s) {
- sb.append('"');
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- switch (c) {
- case '"':
- sb.append("\\\"");
- break;
- case '\\':
- sb.append("\\\\");
- break;
- case '\n':
- sb.append("\\n");
- break;
- case '\r':
- sb.append("\\r");
- break;
- case '\t':
- sb.append("\\t");
- break;
- case '\b':
- sb.append("\\b");
- break;
- case '\f':
- sb.append("\\f");
- break;
- default:
- if (c < 0x20) {
- sb.append(String.format("\\u%04x", (int) c));
- } else {
- sb.append(c);
- }
- }
- }
- sb.append('"');
- }
-
- private static void indent(StringBuilder sb, int level) {
- sb.append(" ".repeat(Math.max(0, level)));
- }
}
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 87ef5372e..6b03d8bfa 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,6 +182,7 @@ public class ProjectSession {
public void projectClosed() {
setDirty(false);
+ app.getPreferencesRepository().resetTransientState();
this.project = null;
this.entityResolver = null;
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 63111e5d6..5a86f8ea8 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
@@ -21,9 +21,12 @@ package org.apache.cayenne.modeler.ui.action;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.configuration.ConfigurationNode;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+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.PreferencesRepository;
import org.apache.cayenne.modeler.toolkit.AppAction;
import org.apache.cayenne.project.Project;
import org.apache.cayenne.project.ProjectSaver;
@@ -80,6 +83,15 @@ public class SaveAsAction extends AppAction {
getProjectSession().pauseFileChangeTracking();
+ PreferencesRepository repo = app.getPreferencesRepository();
+ repo.stageProjectMove(p, projectDir);
+ DataChannelDescriptor descriptor = (DataChannelDescriptor)
p.getRootNode();
+ if (descriptor != null) {
+ for (DataMap map : descriptor.getDataMaps()) {
+ repo.stageDataMapMove(map, projectDir);
+ }
+ }
+
URLResource res = new URLResource(projectDir.toURI().toURL());
ProjectSaver saver = app.getProjectSaver();
saver.saveAs(p, res);
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 d87bd2a7c..85208bba0 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,6 +203,7 @@ public class DataDomainMainView extends ProjectPanel
implements DomainDisplayLis
this,
dataChannelDescriptor,
dataChannelDescriptor.getName());
+ app.getPreferencesRepository().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/main/DataMapMainView.java
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/main/DataMapMainView.java
index a0eb5b9bf..567ca0e33 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
@@ -343,6 +343,7 @@ public class DataMapMainView extends ProjectPanel {
nodesUsingMap.add(node);
}
}
+ app.getPreferencesRepository().stageDataMapRename(map, newName);
map.setName(newName);
for (DataNodeDescriptor node : nodesUsingMap) {
node.getDataMapNames().remove(oldName);