From ce345f40b927ac1bcd1d159ec4383d768a678bbe Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Wed, 16 Aug 2023 00:59:18 +0200
Subject: [PATCH] WIP: MAINT: refactor retrieve properties (move backend-logic
 to backend)

---
 .../java/org/caosdb/server/CaosDBServer.java  |  1 -
 .../server/accessControl/ACMPermissions.java  |  3 -
 .../caosdb/server/database/Replacement.java   | 41 --------------
 .../implementation/MySQL}/DatabaseUtils.java  | 55 +++++--------------
 .../MySQL/MySQLGetAllNames.java               |  1 -
 .../MySQL/MySQLInsertEntityProperties.java    |  1 -
 .../MySQL/MySQLInsertSparseEntity.java        |  1 -
 .../MySQL/MySQLRetrieveAll.java               |  1 -
 .../MySQL/MySQLRetrieveDatatypes.java         |  5 +-
 .../MySQL/MySQLRetrieveParents.java           |  5 +-
 .../MySQL/MySQLRetrievePasswordValidator.java |  2 +-
 .../MySQL/MySQLRetrieveProperties.java        | 20 ++-----
 .../MySQL/MySQLRetrieveSparseEntity.java      |  1 -
 .../MySQL/MySQLRetrieveUser.java              |  2 +-
 .../MySQL/MySQLRetrieveVersionHistory.java    |  1 -
 .../MySQL/MySQLUpdateSparseEntity.java        |  1 -
 .../implementation/MySQL/Replacement.java     | 53 ++++++++++++++++++
 .../interfaces/RetrieveDatatypesImpl.java     |  4 +-
 .../interfaces/RetrieveParentsImpl.java       |  4 +-
 .../transaction/RetrieveDatatypes.java        |  4 +-
 .../backend/transaction/RetrieveParents.java  | 27 ++++++---
 .../transaction/RetrieveProperties.java       |  2 +-
 .../transaction/RetrieveSparseEntity.java     |  7 ++-
 .../server/database/proto/FlatProperty.java   | 13 -----
 .../server/database/proto/ProtoProperty.java  |  6 --
 .../caosdb/server/query/Backreference.java    |  2 +-
 .../org/caosdb/server/query/Conjunction.java  |  2 +-
 .../org/caosdb/server/query/Disjunction.java  |  2 +-
 .../org/caosdb/server/query/Negation.java     |  2 +-
 .../java/org/caosdb/server/query/POV.java     |  2 +-
 .../java/org/caosdb/server/query/Query.java   |  2 +-
 .../org/caosdb/server/query/SubProperty.java  |  2 +-
 .../server/utils/ResultSetIterator.java       |  2 +-
 .../implementation/MySQL}/InsertTest.java     |  6 +-
 34 files changed, 119 insertions(+), 164 deletions(-)
 delete mode 100644 src/main/java/org/caosdb/server/database/Replacement.java
 rename src/main/java/org/caosdb/server/database/{ => backend/implementation/MySQL}/DatabaseUtils.java (87%)
 create mode 100644 src/main/java/org/caosdb/server/database/backend/implementation/MySQL/Replacement.java
 rename src/test/java/org/caosdb/server/database/{ => backend/implementation/MySQL}/InsertTest.java (98%)

diff --git a/src/main/java/org/caosdb/server/CaosDBServer.java b/src/main/java/org/caosdb/server/CaosDBServer.java
index 05fb9485..deca9aae 100644
--- a/src/main/java/org/caosdb/server/CaosDBServer.java
+++ b/src/main/java/org/caosdb/server/CaosDBServer.java
@@ -223,7 +223,6 @@ public class CaosDBServer extends Application {
             public boolean notifyObserver(String e, Observable sender) {
               if (e.equals(ServerProperties.KEY_TIMEZONE)) {
 
-                String[] availableIDs = TimeZone.getAvailableIDs();
                 TimeZone newZoneId =
                     TimeZone.getTimeZone(getServerProperty(ServerProperties.KEY_TIMEZONE));
                 TimeZone.setDefault(newZoneId);
diff --git a/src/main/java/org/caosdb/server/accessControl/ACMPermissions.java b/src/main/java/org/caosdb/server/accessControl/ACMPermissions.java
index 854fc07f..07503692 100644
--- a/src/main/java/org/caosdb/server/accessControl/ACMPermissions.java
+++ b/src/main/java/org/caosdb/server/accessControl/ACMPermissions.java
@@ -26,12 +26,9 @@ import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class ACMPermissions implements Comparable<ACMPermissions> {
 
-  private static Logger LOGGER = LoggerFactory.getLogger(ACMPermissions.class);
   public static final String USER_PARAMETER = "?USER?";
   public static final String REALM_PARAMETER = "?REALM?";
   public static final String ROLE_PARAMETER = "?ROLE?";
diff --git a/src/main/java/org/caosdb/server/database/Replacement.java b/src/main/java/org/caosdb/server/database/Replacement.java
deleted file mode 100644
index 8606d51b..00000000
--- a/src/main/java/org/caosdb/server/database/Replacement.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.caosdb.server.database;
-
-import org.caosdb.server.datatype.ReferenceValue;
-import org.caosdb.server.entity.EntityID;
-import org.caosdb.server.entity.RetrieveEntity;
-import org.caosdb.server.entity.StatementStatus;
-import org.caosdb.server.entity.wrapper.Property;
-
-public class Replacement extends Property {
-
-  public Property replacement;
-  public EntityID replacementId;
-
-  @Override
-  public EntityID getId() {
-    return replacementId;
-  }
-
-  public void setReplacementId(EntityID id) {
-    replacementId.link(id);
-  }
-
-  public Replacement(Property p) {
-    super(p);
-    replacementId = new EntityID();
-    replacement = new Property(new RetrieveEntity());
-
-    replacement.setDomain(p.getDomainEntity());
-    //    replacement.setDatatypeOverride(p.isDatatypeOverride());
-    //    replacement.setDatatype(p.getDatatype());
-    //    replacement.setNameOverride(p.isNameOverride());
-    //    replacement.setName(p.getName());
-    //    replacement.setDescOverride(p.isDescOverride());
-    //    replacement.setDescription(p.getDescription());
-
-    replacement.setId(replacementId);
-    replacement.setStatementStatus(StatementStatus.REPLACEMENT);
-    replacement.setValue(new ReferenceValue(p.getId()));
-    replacement.setPIdx(0);
-  }
-}
diff --git a/src/main/java/org/caosdb/server/database/DatabaseUtils.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseUtils.java
similarity index 87%
rename from src/main/java/org/caosdb/server/database/DatabaseUtils.java
rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseUtils.java
index 6d72d965..0347028b 100644
--- a/src/main/java/org/caosdb/server/database/DatabaseUtils.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseUtils.java
@@ -1,9 +1,10 @@
 /*
- * ** header v3.0
  * This file is a part of the CaosDB Project.
  *
  * Copyright (C) 2018 Research Group Biomedical Physics,
  * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+ * Copyright (C) 2023 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2023 Timm Fitschen <t.fitschen@indiscale.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -17,10 +18,8 @@
  *
  * You should have received a copy of the GNU Affero General Public License
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
  */
-package org.caosdb.server.database;
+package org.caosdb.server.database.backend.implementation.MySQL;
 
 import com.google.common.base.Objects;
 import java.sql.ResultSet;
@@ -46,7 +45,6 @@ import org.caosdb.server.entity.EntityInterface;
 import org.caosdb.server.entity.Message;
 import org.caosdb.server.entity.RetrieveEntity;
 import org.caosdb.server.entity.StatementStatus;
-import org.caosdb.server.entity.wrapper.Parent;
 import org.caosdb.server.entity.wrapper.Property;
 
 public class DatabaseUtils {
@@ -154,13 +152,7 @@ public class DatabaseUtils {
     }
   }
 
-  public static void parseFromSparseEntities(final EntityInterface e, final SparseEntity spe) {
-    if (spe != null) {
-      e.parseSparseEntity(spe);
-    }
-  }
-
-  public static void parseOverrides(final List<FlatProperty> properties, final ResultSet rs)
+  public static void parseOverrides(final List<ProtoProperty> properties, final ResultSet rs)
       throws SQLException {
     while (rs.next()) {
       final int property_id = rs.getInt("property_id");
@@ -187,15 +179,15 @@ public class DatabaseUtils {
     }
   }
 
-  public static List<FlatProperty> parsePropertyResultset(final ResultSet rs) throws SQLException {
-    final List<FlatProperty> ret = new LinkedList<>();
+  public static List<ProtoProperty> parsePropertyResultset(final ResultSet rs) throws SQLException {
+    final List<ProtoProperty> ret = new LinkedList<>();
     while (rs.next()) {
-      FlatProperty fp = new FlatProperty();
-      fp.id = rs.getInt("PropertyID");
-      fp.value = bytes2UTF8(rs.getBytes("PropertyValue"));
-      fp.status = bytes2UTF8(rs.getBytes("PropertyStatus"));
-      fp.idx = rs.getInt("PropertyIndex");
-      ret.add(fp);
+      ProtoProperty pp = new ProtoProperty();
+      pp.id = rs.getInt("PropertyID");
+      pp.value = bytes2UTF8(rs.getBytes("PropertyValue"));
+      pp.status = bytes2UTF8(rs.getBytes("PropertyStatus"));
+      pp.idx = rs.getInt("PropertyIndex");
+      ret.add(pp);
     }
     return ret;
   }
@@ -239,9 +231,9 @@ public class DatabaseUtils {
     return ret;
   }
 
-  public static ArrayList<VerySparseEntity> parseParentResultSet(final ResultSet rs)
+  public static LinkedList<VerySparseEntity> parseParentResultSet(final ResultSet rs)
       throws SQLException {
-    final ArrayList<VerySparseEntity> ret = new ArrayList<VerySparseEntity>();
+    final LinkedList<VerySparseEntity> ret = new LinkedList<>();
     while (rs.next()) {
       final VerySparseEntity vsp = new VerySparseEntity();
       vsp.id = rs.getInt("ParentID");
@@ -254,25 +246,6 @@ public class DatabaseUtils {
     return ret;
   }
 
-  public static <K extends EntityInterface> K parseEntityFromVerySparseEntity(
-      final K entity, final VerySparseEntity vse) {
-    entity.setId(new EntityID(vse.id));
-    entity.setName(vse.name);
-    entity.setRole(vse.role);
-    entity.setDescription(vse.description);
-    return entity;
-  }
-
-  public static void parseParentsFromVerySparseEntity(
-      final EntityInterface entity, final List<VerySparseEntity> pars) {
-    for (final VerySparseEntity vsp : pars) {
-      final Parent p = new Parent(new RetrieveEntity(new EntityID(vsp.id)));
-      p.setName(vsp.name);
-      p.setDescription(vsp.description);
-      entity.addParent(p);
-    }
-  }
-
   public static ArrayList<Property> parseFromProtoProperties(
       EntityInterface entity, List<ProtoProperty> protos) {
     final ArrayList<Property> ret = new ArrayList<Property>();
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java
index 09cae688..474048f1 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java
@@ -5,7 +5,6 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.GetAllNamesImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java
index 5c9ca6f9..f3977068 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java
@@ -33,7 +33,6 @@ import java.util.Deque;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl;
 import org.caosdb.server.database.exceptions.IntegrityException;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java
index 1b945acf..27227926 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java
@@ -26,7 +26,6 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLIntegrityConstraintViolationException;
 import java.sql.Types;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.InsertSparseEntityImpl;
 import org.caosdb.server.database.exceptions.IntegrityException;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java
index f847bf63..9a2ea816 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java
@@ -27,7 +27,6 @@ import java.sql.SQLException;
 import java.util.LinkedList;
 import java.util.List;
 import org.apache.shiro.SecurityUtils;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.RetrieveAllImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java
index e085f051..68524941 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java
@@ -25,8 +25,7 @@ package org.caosdb.server.database.backend.implementation.MySQL;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import org.caosdb.server.database.DatabaseUtils;
+import java.util.List;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
@@ -53,7 +52,7 @@ public class MySQLRetrieveDatatypes extends MySQLTransaction implements Retrieve
           + "FROM entities AS e WHERE e.role='DATATYPE'";
 
   @Override
-  public ArrayList<VerySparseEntity> execute() throws TransactionException {
+  public List<VerySparseEntity> execute() throws TransactionException {
     try {
       final PreparedStatement stmt = prepareStatement(STMT_GET_DATATYPE);
 
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java
index 64ce7e90..1e2a6621 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java
@@ -26,8 +26,7 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
-import java.util.ArrayList;
-import org.caosdb.server.database.DatabaseUtils;
+import java.util.LinkedList;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.RetrieveParentsImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
@@ -43,7 +42,7 @@ public class MySQLRetrieveParents extends MySQLTransaction implements RetrievePa
   private static final String stmtStr = "call retrieveEntityParents(?, ?)";
 
   @Override
-  public ArrayList<VerySparseEntity> execute(final EntityID id, final String version)
+  public LinkedList<VerySparseEntity> execute(final EntityID id, final String version)
       throws TransactionException {
     try {
       ResultSet rs = null;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java
index 1ff7dd7a..9fd7e0a8 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java
@@ -22,7 +22,7 @@
  */
 package org.caosdb.server.database.backend.implementation.MySQL;
 
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.security.NoSuchAlgorithmException;
 import java.sql.PreparedStatement;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java
index c8843f9c..100df4ce 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java
@@ -28,11 +28,9 @@ import java.sql.SQLException;
 import java.sql.Types;
 import java.util.LinkedList;
 import java.util.List;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.RetrievePropertiesImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
-import org.caosdb.server.database.proto.FlatProperty;
 import org.caosdb.server.database.proto.ProtoProperty;
 import org.caosdb.server.entity.EntityID;
 
@@ -92,32 +90,22 @@ public class MySQLRetrieveProperties extends MySQLTransaction implements Retriev
       final long t2 = System.currentTimeMillis();
       addMeasurement(this.getClass().getSimpleName() + ".retrieveFlatPropertiesStage1", t2 - t1);
 
-      final List<FlatProperty> props = DatabaseUtils.parsePropertyResultset(rs);
+      final List<ProtoProperty> properties = DatabaseUtils.parsePropertyResultset(rs);
 
       final PreparedStatement retrieveOverrides = prepareStatement(stmtStr2);
 
-      retrieveOverrides(domain, entity, version, retrieveOverrides, props);
+      retrieveOverrides(domain, entity, version, retrieveOverrides, properties);
 
-      return handleCollectionValues(props);
+      return properties;
     }
   }
 
-  @Deprecated
-  public List<ProtoProperty> handleCollectionValues(List<FlatProperty> props) throws SQLException {
-
-    List<ProtoProperty> result = new LinkedList<>();
-    for (FlatProperty fp : props) {
-      result.add(new ProtoProperty(fp));
-    }
-    return result;
-  }
-
   private void retrieveOverrides(
       final Integer domain,
       final Integer entity,
       final String version,
       final PreparedStatement retrieveOverrides,
-      final List<FlatProperty> props)
+      final List<ProtoProperty> props)
       throws SQLException {
 
     ResultSet rs = null;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java
index ca3bd078..48cd84b3 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java
@@ -26,7 +26,6 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java
index bde1878d..40f036f1 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java
@@ -22,7 +22,7 @@
  */
 package org.caosdb.server.database.backend.implementation.MySQL;
 
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveVersionHistory.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveVersionHistory.java
index 585be49a..6c4c2629 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveVersionHistory.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveVersionHistory.java
@@ -27,7 +27,6 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.LinkedList;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.RetrieveVersionHistoryImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java
index 1c803925..b2d0fb9e 100644
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java
@@ -27,7 +27,6 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.SQLIntegrityConstraintViolationException;
 import java.sql.Types;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.access.Access;
 import org.caosdb.server.database.backend.interfaces.UpdateSparseEntityImpl;
 import org.caosdb.server.database.exceptions.IntegrityException;
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/Replacement.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/Replacement.java
new file mode 100644
index 00000000..66bf99c4
--- /dev/null
+++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/Replacement.java
@@ -0,0 +1,53 @@
+/*
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2023 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2023 Timm Fitschen <t.fitschen@indiscale.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package org.caosdb.server.database.backend.implementation.MySQL;
+
+import org.caosdb.server.datatype.ReferenceValue;
+import org.caosdb.server.entity.EntityID;
+import org.caosdb.server.entity.RetrieveEntity;
+import org.caosdb.server.entity.StatementStatus;
+import org.caosdb.server.entity.wrapper.Property;
+
+public class Replacement extends Property {
+
+  public Property replacement;
+  public EntityID replacementId;
+
+  @Override
+  public EntityID getId() {
+    return replacementId;
+  }
+
+  public void setReplacementId(EntityID id) {
+    replacementId.link(id);
+  }
+
+  public Replacement(Property p) {
+    super(p);
+    replacementId = new EntityID();
+    replacement = new Property(new RetrieveEntity());
+
+    replacement.setDomain(p.getDomainEntity());
+    replacement.setId(replacementId);
+    replacement.setStatementStatus(StatementStatus.REPLACEMENT);
+    replacement.setValue(new ReferenceValue(p.getId()));
+    replacement.setPIdx(0);
+  }
+}
diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java
index 91c68dc5..0886ff43 100644
--- a/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java
+++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java
@@ -22,11 +22,11 @@
  */
 package org.caosdb.server.database.backend.interfaces;
 
-import java.util.ArrayList;
+import java.util.List;
 import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.database.proto.VerySparseEntity;
 
 public interface RetrieveDatatypesImpl extends BackendTransactionImpl {
 
-  public abstract ArrayList<VerySparseEntity> execute() throws TransactionException;
+  public abstract List<VerySparseEntity> execute() throws TransactionException;
 }
diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java
index 9bfddba1..9f7eba82 100644
--- a/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java
+++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java
@@ -22,13 +22,13 @@
  */
 package org.caosdb.server.database.backend.interfaces;
 
-import java.util.ArrayList;
+import java.util.LinkedList;
 import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.database.proto.VerySparseEntity;
 import org.caosdb.server.entity.EntityID;
 
 public interface RetrieveParentsImpl extends BackendTransactionImpl {
 
-  public ArrayList<VerySparseEntity> execute(EntityID id, String version)
+  public LinkedList<VerySparseEntity> execute(EntityID id, String version)
       throws TransactionException;
 }
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveDatatypes.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveDatatypes.java
index b4a726da..1ca9f60e 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveDatatypes.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveDatatypes.java
@@ -22,7 +22,7 @@
  */
 package org.caosdb.server.database.backend.transaction;
 
-import java.util.ArrayList;
+import java.util.List;
 import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
@@ -35,7 +35,7 @@ import org.caosdb.server.entity.container.Container;
 
 public class RetrieveDatatypes extends BackendTransaction {
 
-  private ArrayList<VerySparseEntity> list;
+  private List<VerySparseEntity> list;
 
   @Override
   public void execute() throws TransactionException {
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveParents.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveParents.java
index b551430a..262ee271 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveParents.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveParents.java
@@ -24,15 +24,18 @@
  */
 package org.caosdb.server.database.backend.transaction;
 
-import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
 import org.apache.commons.jcs.access.behavior.ICacheAccess;
 import org.caosdb.server.caching.Cache;
 import org.caosdb.server.database.CacheableBackendTransaction;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.backend.interfaces.RetrieveParentsImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.database.proto.VerySparseEntity;
+import org.caosdb.server.entity.EntityID;
 import org.caosdb.server.entity.EntityInterface;
+import org.caosdb.server.entity.RetrieveEntity;
+import org.caosdb.server.entity.wrapper.Parent;
 
 // TODO Problem with the caching.
 // When an old entity version has a parent which is deleted, the name is
@@ -47,9 +50,9 @@ import org.caosdb.server.entity.EntityInterface;
 // See also a failing test in caosdb-pyinttest:
 // tests/test_version.py::test_bug_cached_parent_name_in_old_version
 public class RetrieveParents
-    extends CacheableBackendTransaction<String, ArrayList<VerySparseEntity>> {
+    extends CacheableBackendTransaction<String, LinkedList<VerySparseEntity>> {
 
-  private static final ICacheAccess<String, ArrayList<VerySparseEntity>> cache =
+  private static final ICacheAccess<String, LinkedList<VerySparseEntity>> cache =
       Cache.getCache("BACKEND_EntityParents");
 
   /**
@@ -71,16 +74,26 @@ public class RetrieveParents
   }
 
   @Override
-  public ArrayList<VerySparseEntity> executeNoCache() throws TransactionException {
+  public LinkedList<VerySparseEntity> executeNoCache() throws TransactionException {
     final RetrieveParentsImpl t = getImplementation(RetrieveParentsImpl.class);
     return t.execute(this.entity.getId(), this.entity.getVersion().getId());
   }
 
   @Override
-  protected void process(final ArrayList<VerySparseEntity> t) throws TransactionException {
+  protected void process(final LinkedList<VerySparseEntity> t) throws TransactionException {
     this.entity.getParents().clear();
 
-    DatabaseUtils.parseParentsFromVerySparseEntity(this.entity, t);
+    parseParentsFromVerySparseEntity(this.entity, t);
+  }
+
+  private void parseParentsFromVerySparseEntity(
+      final EntityInterface entity, final List<VerySparseEntity> pars) {
+    for (final VerySparseEntity vsp : pars) {
+      final Parent p = new Parent(new RetrieveEntity(new EntityID(vsp.id)));
+      p.setName(vsp.name);
+      p.setDescription(vsp.description);
+      entity.addParent(p);
+    }
   }
 
   @Override
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveProperties.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveProperties.java
index caa4b6cf..f9c11303 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveProperties.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveProperties.java
@@ -29,7 +29,7 @@ import java.util.List;
 import org.apache.commons.jcs.access.behavior.ICacheAccess;
 import org.caosdb.server.caching.Cache;
 import org.caosdb.server.database.CacheableBackendTransaction;
-import org.caosdb.server.database.DatabaseUtils;
+import org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils;
 import org.caosdb.server.database.backend.interfaces.RetrievePropertiesImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.database.proto.ProtoProperty;
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java
index aabd490b..f1ba8354 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java
@@ -27,7 +27,6 @@ package org.caosdb.server.database.backend.transaction;
 import org.apache.commons.jcs.access.behavior.ICacheAccess;
 import org.caosdb.server.caching.Cache;
 import org.caosdb.server.database.CacheableBackendTransaction;
-import org.caosdb.server.database.DatabaseUtils;
 import org.caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl;
 import org.caosdb.server.database.exceptions.TransactionException;
 import org.caosdb.server.database.proto.SparseEntity;
@@ -81,8 +80,10 @@ public class RetrieveSparseEntity extends CacheableBackendTransaction<String, Sp
 
   @Override
   protected void process(final SparseEntity t) throws TransactionException {
-    DatabaseUtils.parseFromSparseEntities(this.entity, t);
-    this.entity.setEntityStatus(EntityStatus.VALID);
+    if (t != null) {
+      this.entity.parseSparseEntity(t);
+      this.entity.setEntityStatus(EntityStatus.VALID);
+    }
   }
 
   @Override
diff --git a/src/main/java/org/caosdb/server/database/proto/FlatProperty.java b/src/main/java/org/caosdb/server/database/proto/FlatProperty.java
index b4f0f62a..b92d3def 100644
--- a/src/main/java/org/caosdb/server/database/proto/FlatProperty.java
+++ b/src/main/java/org/caosdb/server/database/proto/FlatProperty.java
@@ -26,19 +26,6 @@ import java.io.Serializable;
 
 public class FlatProperty implements Serializable {
 
-  public FlatProperty() {}
-
-  public FlatProperty(FlatProperty fp) {
-    id = fp.id;
-    value = fp.value;
-    status = fp.status;
-    idx = fp.idx;
-    name = fp.name;
-    desc = fp.desc;
-    type = fp.type;
-    collection = fp.collection;
-  }
-
   private static final long serialVersionUID = 6039288034435124195L;
   public Integer id = null;
   public String value = null;
diff --git a/src/main/java/org/caosdb/server/database/proto/ProtoProperty.java b/src/main/java/org/caosdb/server/database/proto/ProtoProperty.java
index c6cdbd54..7a11cd4d 100644
--- a/src/main/java/org/caosdb/server/database/proto/ProtoProperty.java
+++ b/src/main/java/org/caosdb/server/database/proto/ProtoProperty.java
@@ -28,12 +28,6 @@ import java.util.List;
 public class ProtoProperty extends FlatProperty implements Serializable {
   private static final long serialVersionUID = 7731301985162924975L;
 
-  public ProtoProperty(FlatProperty fp) {
-    super(fp);
-  }
-
-  public ProtoProperty() {}
-
   public List<ProtoProperty> subProperties = null;
   public List<Object> collValues = null;
 }
diff --git a/src/main/java/org/caosdb/server/query/Backreference.java b/src/main/java/org/caosdb/server/query/Backreference.java
index 7d551fd4..b801ffaf 100644
--- a/src/main/java/org/caosdb/server/query/Backreference.java
+++ b/src/main/java/org/caosdb/server/query/Backreference.java
@@ -23,7 +23,7 @@
 package org.caosdb.server.query;
 
 import static java.sql.Types.VARCHAR;
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.sql.CallableStatement;
 import java.sql.Connection;
diff --git a/src/main/java/org/caosdb/server/query/Conjunction.java b/src/main/java/org/caosdb/server/query/Conjunction.java
index 03b33124..59dfd57b 100644
--- a/src/main/java/org/caosdb/server/query/Conjunction.java
+++ b/src/main/java/org/caosdb/server/query/Conjunction.java
@@ -22,7 +22,7 @@
  */
 package org.caosdb.server.query;
 
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.sql.CallableStatement;
 import java.sql.Connection;
diff --git a/src/main/java/org/caosdb/server/query/Disjunction.java b/src/main/java/org/caosdb/server/query/Disjunction.java
index edd2e6da..925ef859 100644
--- a/src/main/java/org/caosdb/server/query/Disjunction.java
+++ b/src/main/java/org/caosdb/server/query/Disjunction.java
@@ -22,7 +22,7 @@
  */
 package org.caosdb.server.query;
 
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.sql.CallableStatement;
 import java.sql.Connection;
diff --git a/src/main/java/org/caosdb/server/query/Negation.java b/src/main/java/org/caosdb/server/query/Negation.java
index cfdfd05e..431124df 100644
--- a/src/main/java/org/caosdb/server/query/Negation.java
+++ b/src/main/java/org/caosdb/server/query/Negation.java
@@ -22,7 +22,7 @@
  */
 package org.caosdb.server.query;
 
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.sql.CallableStatement;
 import java.sql.Connection;
diff --git a/src/main/java/org/caosdb/server/query/POV.java b/src/main/java/org/caosdb/server/query/POV.java
index 0de160cd..ebc35a16 100644
--- a/src/main/java/org/caosdb/server/query/POV.java
+++ b/src/main/java/org/caosdb/server/query/POV.java
@@ -25,7 +25,7 @@ package org.caosdb.server.query;
 import static java.sql.Types.DOUBLE;
 import static java.sql.Types.INTEGER;
 import static java.sql.Types.VARCHAR;
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import de.timmfitschen.easyunits.parser.ParserException;
 import java.sql.CallableStatement;
diff --git a/src/main/java/org/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java
index c4a45863..abaca436 100644
--- a/src/main/java/org/caosdb/server/query/Query.java
+++ b/src/main/java/org/caosdb/server/query/Query.java
@@ -21,7 +21,7 @@
  */
 package org.caosdb.server.query;
 
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.io.Serializable;
 import java.sql.CallableStatement;
diff --git a/src/main/java/org/caosdb/server/query/SubProperty.java b/src/main/java/org/caosdb/server/query/SubProperty.java
index 8ff167ea..d5ce9234 100644
--- a/src/main/java/org/caosdb/server/query/SubProperty.java
+++ b/src/main/java/org/caosdb/server/query/SubProperty.java
@@ -23,7 +23,7 @@
 package org.caosdb.server.query;
 
 import static java.sql.Types.VARCHAR;
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.sql.CallableStatement;
 import java.sql.Connection;
diff --git a/src/main/java/org/caosdb/server/utils/ResultSetIterator.java b/src/main/java/org/caosdb/server/utils/ResultSetIterator.java
index 0912d278..71429f1a 100644
--- a/src/main/java/org/caosdb/server/utils/ResultSetIterator.java
+++ b/src/main/java/org/caosdb/server/utils/ResultSetIterator.java
@@ -1,6 +1,6 @@
 package org.caosdb.server.utils;
 
-import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.bytes2UTF8;
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
diff --git a/src/test/java/org/caosdb/server/database/InsertTest.java b/src/test/java/org/caosdb/server/database/backend/implementation/MySQL/InsertTest.java
similarity index 98%
rename from src/test/java/org/caosdb/server/database/InsertTest.java
rename to src/test/java/org/caosdb/server/database/backend/implementation/MySQL/InsertTest.java
index 0484e623..03bd185c 100644
--- a/src/test/java/org/caosdb/server/database/InsertTest.java
+++ b/src/test/java/org/caosdb/server/database/backend/implementation/MySQL/InsertTest.java
@@ -20,10 +20,10 @@
  *
  * ** end header
  */
-package org.caosdb.server.database;
+package org.caosdb.server.database.backend.implementation.MySQL;
 
-import static org.caosdb.server.database.DatabaseUtils.deriveStage1Inserts;
-import static org.caosdb.server.database.DatabaseUtils.deriveStage2Inserts;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.deriveStage1Inserts;
+import static org.caosdb.server.database.backend.implementation.MySQL.DatabaseUtils.deriveStage2Inserts;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-- 
GitLab