diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java
index be133401d8d24ac89be80a33c36fccd592f071f2..7fedcff4ce97ccb9193b8169f97b856ff6e61632 100644
--- a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java
+++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java
@@ -95,7 +95,7 @@ public class VFSMetadataDAO {
 	 * @param element The curriculum element
 	 * @return The materialized path of the specified element
 	 */
-	private String getMaterializedPathKeys(VFSMetadataImpl parent, VFSMetadataImpl element) {
+	protected String getMaterializedPathKeys(VFSMetadataImpl parent, VFSMetadataImpl element) {
 		if(parent != null) {
 			String parentPathOfKeys = parent.getMaterializedPathKeys();
 			if(parentPathOfKeys == null || "/".equals(parentPathOfKeys)) {
diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java
index eaea4181f98f747e54623cfa480761bd09ebb1fd..279ebbd476acd5913c6fb3926e2250771957118f 100644
--- a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java
@@ -47,6 +47,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.zip.Adler32;
 import java.util.zip.Checksum;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.core.commons.modules.bc.FolderConfig;
 import org.olat.core.commons.modules.bc.FolderLicenseHandler;
@@ -74,7 +75,6 @@ import org.olat.core.commons.services.vfs.model.VFSRevisionImpl;
 import org.olat.core.gui.control.Event;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.StringHelper;
@@ -1075,6 +1075,27 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv
 			dbInstance.commit();
 		}
 	}
+	
+	private VFSMetadata checkParentLine(VFSMetadata metadata, VFSMetadata parent) {
+		if(metadata == null || parent == null) {
+			return metadata;
+		}
+
+		VFSMetadata persistedParent = ((VFSMetadataImpl)metadata).getParent();
+		String materializedPath = metadataDao.getMaterializedPathKeys((VFSMetadataImpl)parent, (VFSMetadataImpl)metadata);
+		if(!persistedParent.equals(parent)) {
+			((VFSMetadataImpl)metadata).setMaterializedPathKeys(materializedPath);
+			((VFSMetadataImpl)metadata).setParent(parent);
+			return metadataDao.updateMetadata(metadata);
+		}
+
+		String pathKeys = ((VFSMetadataImpl)metadata).getMaterializedPathKeys();
+		if(!pathKeys.equals(materializedPath)) {
+			((VFSMetadataImpl)metadata).setMaterializedPathKeys(materializedPath);
+			return metadataDao.updateMetadata(metadata);
+		}
+		return metadata;
+	}
 
 	public void migrateDirectories(File folder) throws IOException {
 		Deque<VFSMetadata> parentLine = new LinkedList<>();
@@ -1087,18 +1108,15 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv
 				if(directory.isHidden() || VFSRepositoryModule.canMeta(directory) != VFSConstants.YES) {
 					return FileVisitResult.SKIP_SUBTREE;
 				}
-				if(dir.getNameCount() > 50) {
+				if(dir.getNameCount() > 50 || parentLine.size() > 50) {
 					log.error("More than 50 directories deep. Stop migrating metadata: {}", directory);
 					return FileVisitResult.SKIP_SUBTREE;
 				}
 				
 				VFSMetadata parent = parentLine.peekLast();
 				VFSMetadata metadata = migrateMetadata(dir.toFile(), parent);
+				metadata = checkParentLine(metadata, parent);
 				parentLine.add(metadata);
-				if(metadata != null && "migrated".equals(metadata.getMigrated())) {
-					dbInstance.commitAndCloseSession();
-					return FileVisitResult.SKIP_SUBTREE;
-				}
 				dbInstance.commit();
 				return FileVisitResult.CONTINUE;
 			}
@@ -1107,7 +1125,8 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv
 			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
 				File f = file.toFile();
 				if(!f.isHidden() && VFSRepositoryModule.canMeta(f) == VFSConstants.YES) {
-					migrateMetadata(file.toFile(), parentLine.getLast());
+					VFSMetadata metadata = migrateMetadata(file.toFile(), parentLine.getLast());
+					checkParentLine(metadata, parentLine.getLast());
 					
 					migrationCounter.incrementAndGet();
 					if(migrationCounter.get() % 25 == 0) {
diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties
index 8b7d42950b9384d9b59ef090d88a372aaa487ba3..8fab8322865da33eb47a071773424b380d14a789 100644
--- a/src/main/resources/serviceconfig/olat.properties
+++ b/src/main/resources/serviceconfig/olat.properties
@@ -1247,8 +1247,8 @@ ldap.learningResourceManagerRoleValue=
 # Build properties
 #####
 application.name=OpenOLAT
-build.version=14.0.3
-build.identifier=openolat1403-dev
+build.version=14.0.4
+build.identifier=openolat1404-dev
 build.repo.revision=local-devel
 
 #####