diff --git a/CHANGELOG.md b/CHANGELOG.md index a38468f985ee03e7f18a990ce5fee90368a74a23..e9c9bf023c63fab22c7e9e8fd8eb65b3d7ef9043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +* Semi-fixed a bug which occurs when retrieving old versions of entities which + reference entities which have been deleted in the mean time. The current fix + adds a warning message to the reference property in question and sets the + value to NULL. This might even be desired behavior, however this would have + to finally specified during the Delete/Forget phase of the implementation of + the versioning. - Inheritance job cannot handle inheritance from same container (!54) * Bug in the query parser (MR!56) - The parser would throw an error when the query contains a conjunction or disjunction filter with a first element which diff --git a/src/main/java/org/caosdb/server/database/DatabaseUtils.java b/src/main/java/org/caosdb/server/database/DatabaseUtils.java index c985c1b9bc62270ccf6c5904b1c7f0147bb20de0..d5910eb9a93003106369f87f50bec1c0013a61bf 100644 --- a/src/main/java/org/caosdb/server/database/DatabaseUtils.java +++ b/src/main/java/org/caosdb/server/database/DatabaseUtils.java @@ -258,7 +258,8 @@ public class DatabaseUtils { } } - private static void replace(final Property p, final HashMap<Integer, Property> domainMap) { + private static void replace( + final Property p, final HashMap<Integer, Property> domainMap, boolean isHead) { // ... find the corresponding domain and replace it ReferenceValue ref; try { @@ -267,6 +268,17 @@ public class DatabaseUtils { throw new RuntimeException("This should never happen."); } final EntityInterface replacement = domainMap.get((ref.getId())); + if (replacement == null) { + if (isHead) { + throw new NullPointerException("Replacement was null"); + } + // entity has been deleted (we are processing properties of an old entity version) + p.setValue(null); + p.addWarning( + new Message( + "The referenced entity has been deleted in the mean time and is not longer available.")); + return; + } if (replacement.isDescOverride()) { p.setDescOverride(true); p.setDescription(replacement.getDescription()); @@ -314,15 +326,18 @@ public class DatabaseUtils { } // loop over all properties + boolean isHead = + e.getVersion().getSuccessors() == null || e.getVersion().getSuccessors().isEmpty(); for (final Property p : protoProperties) { + // if this is a replacement if (p.getStatementStatus() == StatementStatus.REPLACEMENT) { - replace(p, domainMap); + replace(p, domainMap, isHead); } for (final Property subP : p.getProperties()) { if (subP.getStatementStatus() == StatementStatus.REPLACEMENT) { - replace(subP, domainMap); + replace(subP, domainMap, isHead); } } diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntity.java index 2601367b7312331a981d2b352040962ac3a98a43..38cd7073613e6477d013f8923aaecfc188a3c234 100644 --- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntity.java @@ -102,12 +102,12 @@ public class RetrieveFullEntity extends BackendTransaction { execute(new RetrieveSparseEntity(e)); if (e.getEntityStatus() == EntityStatus.VALID) { + execute(new RetrieveVersionInfo(e)); if (e.getRole() == Role.QueryTemplate) { execute(new RetrieveQueryTemplateDefinition(e)); } execute(new RetrieveParents(e)); execute(new RetrieveProperties(e)); - execute(new RetrieveVersionInfo(e)); // recursion! retrieveSubEntities calls retrieveFull sometimes, but with reduced selectors. if (selections != null && !selections.isEmpty()) { diff --git a/src/main/java/org/caosdb/server/entity/Entity.java b/src/main/java/org/caosdb/server/entity/Entity.java index 28f42308e303c0315b432c017fd2147119c5b346..8578191c40c229ae1b9f0e873d35690c55cf2bfc 100644 --- a/src/main/java/org/caosdb/server/entity/Entity.java +++ b/src/main/java/org/caosdb/server/entity/Entity.java @@ -957,7 +957,8 @@ public class Entity extends AbstractObservable implements EntityInterface { @Override public String toString() { - return (hasId() ? "(" + getId().toString() + ")" : "()") + return (getRole().toString()) + + (hasId() ? "(" + getId().toString() + ")" : "()") + (hasCuid() ? "[" + getCuid() + "]" : "[]") + (hasName() ? "(" + getName() + ")" : "()") + (hasDatatype() ? "{" + getDatatype().toString() + "}" : "{}"); diff --git a/src/main/java/org/caosdb/server/entity/wrapper/Property.java b/src/main/java/org/caosdb/server/entity/wrapper/Property.java index 305a9d83cbfad835baa547670fae8e186417330d..b3ce45b56527e40382d3971a61b43f9bc054d21f 100644 --- a/src/main/java/org/caosdb/server/entity/wrapper/Property.java +++ b/src/main/java/org/caosdb/server/entity/wrapper/Property.java @@ -120,7 +120,7 @@ public class Property extends EntityWrapper { @Override public String toString() { - return "IMPLPROPERTY " + this.entity.toString(); + return "IMPLPROPERTY (" + this.getStatementStatus() + ")" + this.entity.toString(); } public void setIsName(final boolean b) {