[Fix] Fixed AuditingElementMapFacade.undoVersion() not setting correct version for updates

This commit is contained in:
Robert von Burg 2023-07-20 16:53:10 +02:00
parent fb45b4178a
commit d40c63032c
Signed by: eitch
GPG Key ID: 75DB9C85C74331F7
4 changed files with 107 additions and 191 deletions

View File

@ -40,8 +40,7 @@ import li.strolch.persistence.api.StrolchTransaction;
* <b>Note:</b> * <b>Note:</b>
* </p> * </p>
* *
* @param <T> * @param <T> the object instance being managed
* the object instance being managed
* *
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*/ */
@ -50,10 +49,8 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns true if the underlying persistence layer has elements with the given type * Returns true if the underlying persistence layer has elements with the given type
* *
* @param tx * @param tx the open {@link StrolchTransaction}
* the open {@link StrolchTransaction} * @param type the type of element to check for
* @param type
* the type of element to check for
* *
* @return true if the underlying persistence layer has elements with the given type * @return true if the underlying persistence layer has elements with the given type
*/ */
@ -62,12 +59,9 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns true if the underlying persistence layer has an element with the given type and ID * Returns true if the underlying persistence layer has an element with the given type and ID
* *
* @param tx * @param tx the open {@link StrolchTransaction}
* the open {@link StrolchTransaction} * @param type the type of element to check for
* @param type * @param id the ID of the element to check for
* the type of element to check for
* @param id
* the ID of the element to check for
* *
* @return true if the underlying persistence layer has an element with the given type and ID * @return true if the underlying persistence layer has an element with the given type and ID
*/ */
@ -76,8 +70,7 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns the number of elements regardless of type in the underlying persistence layer * Returns the number of elements regardless of type in the underlying persistence layer
* *
* @param tx * @param tx the open {@link StrolchTransaction}
* the open {@link StrolchTransaction}
* *
* @return the number of elements regardless of type in the underlying persistence layer * @return the number of elements regardless of type in the underlying persistence layer
*/ */
@ -86,10 +79,8 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns the number of elements of the given type in the underlying persistence layer * Returns the number of elements of the given type in the underlying persistence layer
* *
* @param tx * @param tx the open {@link StrolchTransaction}
* the open {@link StrolchTransaction} * @param type the type of element for which the number of elements is to be queried
* @param type
* the type of element for which the number of elements is to be queried
* *
* @return the number of elements of the given type in the underlying persistence layer * @return the number of elements of the given type in the underlying persistence layer
*/ */
@ -98,10 +89,8 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns a copy of the element with the type "Template" and the id = type * Returns a copy of the element with the type "Template" and the id = type
* *
* @param tx * @param tx the open {@link StrolchTransaction}
* the open {@link StrolchTransaction} * @param type The template id to return
* @param type
* The template id to return
* *
* @return the template, or null if it does not exist * @return the template, or null if it does not exist
*/ */
@ -110,29 +99,22 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns a copy of the element with the type "Template" and the id = type * Returns a copy of the element with the type "Template" and the id = type
* *
* @param tx * @param tx the open {@link StrolchTransaction}
* the open {@link StrolchTransaction} * @param type The template id to return
* @param type * @param assertExists if true, and element does not exist, then a {@link StrolchException} is thrown
* The template id to return
* @param assertExists
* if true, and element does not exist, then a {@link StrolchException} is thrown
* *
* @return the template, or null if it does not exist * @return the template, or null if it does not exist
* *
* @throws StrolchException * @throws StrolchException if the template does not exist
* if the template does not exist
*/ */
T getTemplate(StrolchTransaction tx, String type, boolean assertExists) throws StrolchException; T getTemplate(StrolchTransaction tx, String type, boolean assertExists) throws StrolchException;
/** /**
* Retrieves the element with the given type and id, or null if it does not exist * Retrieves the element with the given type and id, or null if it does not exist
* *
* @param tx * @param tx the open transaction
* the open transaction * @param type the type of the element to retrieve
* @param type * @param id the id of the element to retrieve
* the type of the element to retrieve
* @param id
* the id of the element to retrieve
* *
* @return the element with the type and id, or null if it does not exist * @return the element with the type and id, or null if it does not exist
*/ */
@ -141,33 +123,24 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Retrieves the element with the given type and id, or null if it does not exist * Retrieves the element with the given type and id, or null if it does not exist
* *
* @param tx * @param tx the open transaction
* the open transaction * @param type the type of the element to retrieve
* @param type * @param id the id of the element to retrieve
* the type of the element to retrieve * @param assertExists if true, and element does not exist, then a {@link StrolchException} is thrown
* @param id
* the id of the element to retrieve
* @param assertExists
* if true, and element does not exist, then a {@link StrolchException} is thrown
* *
* @return the element with the type and id, or null if it does not exist * @return the element with the type and id, or null if it does not exist
* *
* @throws StrolchException * @throws StrolchException if the element does not exist
* if the element does not exist
*/ */
T getBy(StrolchTransaction tx, String type, String id, boolean assertExists) throws StrolchException; T getBy(StrolchTransaction tx, String type, String id, boolean assertExists) throws StrolchException;
/** /**
* Retrieves the specific version of the element with the given type and id, or null if it does not exist * Retrieves the specific version of the element with the given type and id, or null if it does not exist
* *
* @param tx * @param tx the open transaction
* the open transaction * @param type the type of the element to retrieve
* @param type * @param id the id of the element to retrieve
* the type of the element to retrieve * @param version the version to get
* @param id
* the id of the element to retrieve
* @param version
* the version to get
* *
* @return the element with the type and id, or null if it does not exist * @return the element with the type and id, or null if it does not exist
*/ */
@ -176,75 +149,57 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Retrieves the specific version of the element with the given type and id, or null if it does not exist * Retrieves the specific version of the element with the given type and id, or null if it does not exist
* *
* @param tx * @param tx the open transaction
* the open transaction * @param type the type of the element to retrieve
* @param type * @param id the id of the element to retrieve
* the type of the element to retrieve * @param version the version to get
* @param id * @param assertExists if true, and element does not exist, then a {@link StrolchException} is thrown
* the id of the element to retrieve
* @param version
* the version to get
* @param assertExists
* if true, and element does not exist, then a {@link StrolchException} is thrown
* *
* @return the element with the type and id, or null if it does not exist * @return the element with the type and id, or null if it does not exist
* *
* @throws StrolchException * @throws StrolchException if the element does not exist
* if the element does not exist
*/ */
T getBy(StrolchTransaction tx, String type, String id, int version, boolean assertExists) T getBy(StrolchTransaction tx, String type, String id, int version, boolean assertExists) throws StrolchException;
throws StrolchException;
/** /**
* Returns the element which is referenced by the given {@link StringParameter}. A reference {@link Parameter} must * Returns the element which is referenced by the given {@link StringParameter}. A reference {@link Parameter} must
* have its interpretation set to the element type being referenced e.g. s * have its interpretation set to the element type being referenced e.g. s
* {@link StrolchModelConstants#INTERPRETATION_ORDER_REF} and the UOM must be set to the element's type and the value is * {@link StrolchModelConstants#INTERPRETATION_ORDER_REF} and the UOM must be set to the element's type and the
* the id of the element * value is the id of the element
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param refP the {@link StringParameter} which references an element
* @param refP * @param assertExists if true, and element does not exist, then a {@link StrolchException} is thrown
* the {@link StringParameter} which references an element
* @param assertExists
* if true, and element does not exist, then a {@link StrolchException} is thrown
* *
* @return the element found, or null if it does not exist * @return the element found, or null if it does not exist
* *
* @throws StrolchException * @throws StrolchException if the {@link StringParameter} is not a properly configured as a reference parameter
* if the {@link StringParameter} is not a properly configured as a reference parameter
*/ */
T getBy(StrolchTransaction tx, StringParameter refP, boolean assertExists) throws StrolchException; T getBy(StrolchTransaction tx, StringParameter refP, boolean assertExists) throws StrolchException;
/** /**
* Returns all elements which are referenced by the given {@link StringListParameter}. A reference {@link Parameter} * Returns all elements which are referenced by the given {@link StringListParameter}. A reference {@link Parameter}
* must have its interpretation set to the element type being referenced e.g. s * must have its interpretation set to the element type being referenced e.g. s
* {@link StrolchModelConstants#INTERPRETATION_ORDER_REF} and the UOM must be set to the element's type and the value is * {@link StrolchModelConstants#INTERPRETATION_ORDER_REF} and the UOM must be set to the element's type and the
* the id of the element * value is the id of the element
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param refP the {@link StringListParameter} which references an element
* @param refP * @param assertExists if true, and element does not exist, then a {@link StrolchException} is thrown
* the {@link StringListParameter} which references an element
* @param assertExists
* if true, and element does not exist, then a {@link StrolchException} is thrown
* *
* @return the list of elements found, or the empty list if they do not exist. <b>Note:</b> Any missing elements are * @return the list of elements found, or the empty list if they do not exist. <b>Note:</b> Any missing elements are
* not returned! * not returned!
* *
* @throws StrolchException * @throws StrolchException if the {@link StringParameter} is not a properly configured as a reference parameter
* if the {@link StringParameter} is not a properly configured as a reference parameter
*/ */
List<T> getBy(StrolchTransaction tx, StringListParameter refP, boolean assertExists) throws StrolchException; List<T> getBy(StrolchTransaction tx, StringListParameter refP, boolean assertExists) throws StrolchException;
/** /**
* Queries and returns all the versions of the element with the given type and ID * Queries and returns all the versions of the element with the given type and ID
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param type the type of the element to be queried
* @param type * @param id the id of the element to be queried
* the type of the element to be queried
* @param id
* the id of the element to be queried
* *
* @return all the versions of the element with the given type and ID * @return all the versions of the element with the given type and ID
*/ */
@ -253,12 +208,9 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns the latest version of the given element, or -1 if no version available * Returns the latest version of the given element, or -1 if no version available
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param type the type of the element
* @param type * @param id the id of the element
* the type of the element
* @param id
* the id of the element
* *
* @return the latest version of the element, or -1 if no version available * @return the latest version of the element, or -1 if no version available
*/ */
@ -267,8 +219,7 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns all elements in the underlying persistence layer regardless of type * Returns all elements in the underlying persistence layer regardless of type
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance
* *
* @return all elements in the underlying persistence layer regardless of type * @return all elements in the underlying persistence layer regardless of type
*/ */
@ -277,10 +228,8 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns all elements in the underlying persistence layer of the given type * Returns all elements in the underlying persistence layer of the given type
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param type the type of the elements to retrieve
* @param type
* the type of the elements to retrieve
* *
* @return all elements in the underlying persistence layer of the given type * @return all elements in the underlying persistence layer of the given type
*/ */
@ -289,10 +238,8 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns a {@link Stream} for all elements for the given types * Returns a {@link Stream} for all elements for the given types
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param types the types of the elements
* @param types
* the types of the elements
* *
* @return a stream for the elements * @return a stream for the elements
*/ */
@ -301,8 +248,7 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns all the types known in the underlying persistence layer * Returns all the types known in the underlying persistence layer
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance
* *
* @return all the types known in the underlying persistence layer * @return all the types known in the underlying persistence layer
*/ */
@ -311,8 +257,7 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns all keys/IDs of all elements in the underlying persistence layer, regardless of type * Returns all keys/IDs of all elements in the underlying persistence layer, regardless of type
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance
* *
* @return all keys/IDs of all elements in the underlying persistence layer, regardless of type * @return all keys/IDs of all elements in the underlying persistence layer, regardless of type
*/ */
@ -321,10 +266,8 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Returns all keys/IDs of all elements in the underlying persistence layer, of the given type * Returns all keys/IDs of all elements in the underlying persistence layer, of the given type
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param type the type of the element to retrieve the keys for
* @param type
* the type of the element to retrieve the keys for
* *
* @return all keys/IDs of all elements in the underlying persistence layer, of the given type * @return all keys/IDs of all elements in the underlying persistence layer, of the given type
*/ */
@ -333,78 +276,60 @@ public interface ElementMap<T extends StrolchRootElement> {
/** /**
* Adds the given element to the underlying persistence layer. The element may not already exist * Adds the given element to the underlying persistence layer. The element may not already exist
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param element the element to add
* @param element
* the element to add
* *
* @throws StrolchPersistenceException * @throws StrolchPersistenceException if an element already exists with the same ID
* if an element already exists with the same ID
*/ */
void add(StrolchTransaction tx, T element) throws StrolchPersistenceException; void add(StrolchTransaction tx, T element) throws StrolchPersistenceException;
/** /**
* Adds the given elements to the underlying persistence layer. None of the elements may already exist * Adds the given elements to the underlying persistence layer. None of the elements may already exist
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param elements the elements to add
* @param elements
* the elements to add
* *
* @throws StrolchPersistenceException * @throws StrolchPersistenceException if an element already exists with the same ID
* if an element already exists with the same ID
*/ */
void addAll(StrolchTransaction tx, List<T> elements) throws StrolchPersistenceException; void addAll(StrolchTransaction tx, List<T> elements) throws StrolchPersistenceException;
/** /**
* Updates the existing element * Updates the existing element
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param element the element to update
* @param element
* the element to update
* *
* @throws StrolchPersistenceException * @throws StrolchPersistenceException if the element does not exist
* if the element does not exist
*/ */
void update(StrolchTransaction tx, T element) throws StrolchPersistenceException; void update(StrolchTransaction tx, T element) throws StrolchPersistenceException;
/** /**
* Updates all the existing elements * Updates all the existing elements
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param elements the elements to update
* @param elements
* the elements to update
* *
* @throws StrolchPersistenceException * @throws StrolchPersistenceException if any of the elements don't yet exist
* if any of the elements don't yet exist
*/ */
void updateAll(StrolchTransaction tx, List<T> elements) throws StrolchPersistenceException; void updateAll(StrolchTransaction tx, List<T> elements) throws StrolchPersistenceException;
/** /**
* Removes the given element * Removes the given element
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param element the element to be removed
* @param element
* the element to be removed
* *
* @throws StrolchPersistenceException * @throws StrolchPersistenceException if the element does not exist
* if the element does not exist
*/ */
void remove(StrolchTransaction tx, T element) throws StrolchPersistenceException; void remove(StrolchTransaction tx, T element) throws StrolchPersistenceException;
/** /**
* Removes the given elements * Removes the given elements
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param elements the elements to be removed
* @param elements
* the elements to be removed
* *
* @throws StrolchPersistenceException * @throws StrolchPersistenceException if any of the elements don't yet exist
* if any of the elements don't yet exist
*/ */
void removeAll(StrolchTransaction tx, List<T> elements) throws StrolchPersistenceException; void removeAll(StrolchTransaction tx, List<T> elements) throws StrolchPersistenceException;
@ -417,8 +342,7 @@ public interface ElementMap<T extends StrolchRootElement> {
* <b>Note:</b> This method ignores versioning. Do NOT call this method unless you want to clear the model! * <b>Note:</b> This method ignores versioning. Do NOT call this method unless you want to clear the model!
* </p> * </p>
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance
* *
* @return the number of elements removed * @return the number of elements removed
*/ */
@ -433,10 +357,8 @@ public interface ElementMap<T extends StrolchRootElement> {
* <b>Note:</b> This method ignores versioning. Do NOT call this method unless you want to clear the model! * <b>Note:</b> This method ignores versioning. Do NOT call this method unless you want to clear the model!
* </p> * </p>
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param type the type of elements to remove
* @param type
* the type of elements to remove
* *
* @return the number of elements removed * @return the number of elements removed
*/ */
@ -455,16 +377,15 @@ public interface ElementMap<T extends StrolchRootElement> {
* {@link #revertToVersion(StrolchTransaction, StrolchRootElement)} method should be used. * {@link #revertToVersion(StrolchTransaction, StrolchRootElement)} method should be used.
* </p> * </p>
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param element the element which is to be reverted to a previous version
* @param element
* the element which is to be reverted to a previous version
* *
* @throws StrolchException * @return the version before the given version. If the given version is the first version, null is returned
* if the version does not exist, if this version is not the latest version, if the previous version is *
* missing or other problems arise * @throws StrolchException if the version does not exist, if this version is not the latest version, if the
* previous version is missing or other problems arise
*/ */
void undoVersion(StrolchTransaction tx, T element) throws StrolchException; T undoVersion(StrolchTransaction tx, T element) throws StrolchException;
/** /**
* <p> * <p>
@ -478,15 +399,12 @@ public interface ElementMap<T extends StrolchRootElement> {
* that the history is not changed and that a new version is saved but with the version of the element specified. * that the history is not changed and that a new version is saved but with the version of the element specified.
* </p> * </p>
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param element the version of the element to revert to
* @param element
* the version of the element to revert to
* *
* @return the new version of the element * @return the new version of the element
* *
* @throws StrolchException * @throws StrolchException if the version does not exist
* if the version does not exist
*/ */
T revertToVersion(StrolchTransaction tx, T element) throws StrolchException; T revertToVersion(StrolchTransaction tx, T element) throws StrolchException;
@ -502,19 +420,14 @@ public interface ElementMap<T extends StrolchRootElement> {
* that the history is not changed and that a new version is saved but with the version of the element specified. * that the history is not changed and that a new version is saved but with the version of the element specified.
* </p> * </p>
* *
* @param tx * @param tx the {@link StrolchTransaction} instance
* the {@link StrolchTransaction} instance * @param type the type of the element to revert to
* @param type * @param id the id of the element to revert to
* the type of the element to revert to * @param version the version of the specified element to revert to
* @param id
* the id of the element to revert to
* @param version
* the version of the specified element to revert to
* *
* @return the new version of the element * @return the new version of the element
* *
* @throws StrolchException * @throws StrolchException if the version does not exist
* if the version does not exist
*/ */
T revertToVersion(StrolchTransaction tx, String type, String id, int version) throws StrolchException; T revertToVersion(StrolchTransaction tx, String type, String id, int version) throws StrolchException;
} }

View File

@ -407,17 +407,19 @@ public abstract class AuditingElementMapFacade<T extends StrolchRootElement> imp
} }
@Override @Override
public void undoVersion(StrolchTransaction tx, T element) throws StrolchException { public T undoVersion(StrolchTransaction tx, T element) throws StrolchException {
assertNotReadOnly(); assertNotReadOnly();
this.elementMap.undoVersion(tx, element); T previous = this.elementMap.undoVersion(tx, element);
if (element.getVersion().isFirstVersion()) { if (element.getVersion().isFirstVersion()) {
if (this.deleted == null) if (this.deleted == null)
this.deleted = new HashSet<>(); this.deleted = new HashSet<>();
this.deleted.add(element); this.deleted.add(element);
return null;
} else { } else {
if (this.updated == null) if (this.updated == null)
this.updated = new HashSet<>(); this.updated = new HashSet<>();
this.updated.add(element); this.updated.add(previous);
return previous;
} }
} }
} }

View File

@ -227,8 +227,7 @@ public abstract class CachedElementMap<T extends StrolchRootElement> extends Tra
T versionT = getBy(tx, type, id, version, true); T versionT = getBy(tx, type, id, version, true);
// create the new version // create the new version
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked") T clone = (T) versionT.getClone();
T clone = (T) versionT.getClone();
clone.setVersion(current.getVersion()); clone.setVersion(current.getVersion());
// save the new version // save the new version
@ -239,7 +238,7 @@ public abstract class CachedElementMap<T extends StrolchRootElement> extends Tra
} }
@Override @Override
public void undoVersion(StrolchTransaction tx, T element) throws StrolchException { public T undoVersion(StrolchTransaction tx, T element) throws StrolchException {
if (!this.realm.isVersioningEnabled()) if (!this.realm.isVersioningEnabled())
throw new StrolchPersistenceException("Can not undo a version if versioning is not enabled!"); throw new StrolchPersistenceException("Can not undo a version if versioning is not enabled!");
@ -259,10 +258,12 @@ public abstract class CachedElementMap<T extends StrolchRootElement> extends Tra
if (elementVersion.isFirstVersion()) { if (elementVersion.isFirstVersion()) {
super.remove(tx, element); super.remove(tx, element);
getDbDao(tx).remove(element); getDbDao(tx).remove(element);
return null;
} else { } else {
T previous = getBy(tx, type, id, elementVersion.getPreviousVersion(), true); T previous = getBy(tx, type, id, elementVersion.getPreviousVersion(), true);
super.internalUpdate(tx, previous); super.internalUpdate(tx, previous);
getDbDao(tx).removeVersion(current); getDbDao(tx).removeVersion(current);
return previous;
} }
} }

View File

@ -416,7 +416,7 @@ public abstract class TransientElementMap<T extends StrolchRootElement> implemen
} }
@Override @Override
public void undoVersion(StrolchTransaction tx, T element) throws StrolchException { public T undoVersion(StrolchTransaction tx, T element) throws StrolchException {
throw new IllegalStateException("Transient mode does not support versioning"); throw new IllegalStateException("Transient mode does not support versioning");
} }