You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hop.apache.org by ha...@apache.org on 2026/08/21 07:27:34 UTC

(hop) branch main updated: create a copy utility and remove the need for clone and copy constructors in transforms/actions (#8031)

This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new 718a7269a9 create a copy utility and remove the need for clone and copy constructors in transforms/actions (#8031)
718a7269a9 is described below

commit 718a7269a951e7f5f3fb8a48e3bf408f3f723db5
Author: Hans Van Akelyen <ha...@gmail.com>
AuthorDate: Fri Aug 21 09:27:28 2026 +0200

    create a copy utility and remove the need for clone and copy constructors in transforms/actions (#8031)
    
    * deep copy metadata properties when cloning transform and action metadata. fixes #8022
    
    Object.clone() is shallow, so a cloned ITransformMeta or IAction keeps sharing
    every list, map and nested value object with the original. The pipeline editor
    relies on cloned snapshots in two places and the sharing broke both:
    
    - editTransform() decides whether a dialog changed anything by comparing the XML
      of a snapshot taken before the dialog opened against one taken after OK. The
      snapshot shared the live lists, so dialogs that refill a list in place - Add
      constants, the Data Grid Meta tab, Insert/Update, Update, Table output and
      around twenty more - serialized identically and their edits were silently not
      marked as changed. The reported workaround, moving the transform afterwards,
      worked because setLocation() sets the flag directly.
    
    - The same snapshot is stored as the undo entry, so undo either did nothing or
      rolled back only the properties that survived the shallow copy, leaving the
      transform in a state the user never had.
    
    BaseTransformMeta.clone() and ActionBase.clone() now deep copy the state
    described by the @HopMetadataProperty annotations, which is exactly the state
    that gets persisted, compared and restored. Live references - other transforms,
    metadata providers, caches - stay shared, as the javadoc on clone() intends.
    
    One generic implementation makes the hand written copies redundant: 211 clone()
    overrides and 122 copy constructors are removed. The 12 overrides that remain
    each do something the generic copy cannot: a covariant return required by
    ICsvInputAwareMeta, null defaulting, unannotated runtime state, or a copy
    constructor that normalizes a value.
    
    This also fixes AvroOutputMeta, CalculatorMeta and MergeJoinMeta, whose hand
    written clone() silently dropped most of their fields, and removes the
    assignment in ActionMail.clone() that wrote the copy's list back onto the
    original.
    
    Co-Authored-By: Claude Opus 5 (1M context) <no...@anthropic.com>
    
    * keep canvas edits out of the dialog changed flag. fixes #8022
    
    Transform and action dialogs are not modal, so the canvas stays live while one
    is open. Every dialog captures the changed flag when it is constructed and
    restores it in cancel(). A transform's entire dirty state was a single boolean
    on the inner ITransformMeta, and TransformMeta.setLocation() wrote to that same
    boolean, so dragging a transform while its dialog was open and then pressing
    Cancel discarded the move: the transform stayed at its new position while the
    pipeline reported no changes, and the move was lost on close.
    
    TransformMeta and ActionMeta now keep their own flag for the state they own -
    position, number of copies, row distribution - and hasChanged() reports the two
    together. A dialog's Cancel reaches only the transform's own settings, so it can
    still roll back an edit in progress without touching what the canvas did.
    
    Co-Authored-By: Claude Opus 5 (1M context) <no...@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 5 (1M context) <no...@anthropic.com>
---
 .../hop/metadata/util/HopMetadataCopyUtil.java     | 243 +++++++++++++++++++++
 .../hop/metadata/util/HopMetadataCopyUtilTest.java | 180 +++++++++++++++
 .../hop/pipeline/transform/BaseTransformMeta.java  |   8 +
 .../hop/pipeline/transform/TransformMeta.java      |  30 ++-
 .../org/apache/hop/workflow/action/ActionBase.java |   8 +
 .../org/apache/hop/workflow/action/ActionMeta.java |  25 ++-
 .../transform/TransformMetaChangedFlagTest.java    | 106 +++++++++
 .../workflow/action/ActionMetaChangedFlagTest.java |  81 +++++++
 .../hop/workflow/actions/abort/ActionAbort.java    |  11 -
 .../ActionAddResultFilenames.java                  |  13 --
 .../checkfilelocked/ActionCheckFilesLocked.java    |   5 -
 .../actions/columnsexist/ActionColumnsExist.java   |  13 --
 .../actions/copyfiles/ActionCopyFiles.java         |  30 +--
 .../ActionCopyMoveResultFilenames.java             |  33 ---
 .../actions/createfolder/ActionCreateFolder.java   |  11 -
 .../apache/hop/workflow/actions/dbt/ActionDbt.java |  10 -
 .../hop/workflow/actions/delay/ActionDelay.java    |  11 -
 .../actions/deletefile/ActionDeleteFile.java       |  11 -
 .../actions/deletefiles/ActionDeleteFiles.java     |  13 --
 .../actions/deletefolders/ActionDeleteFolders.java |  14 --
 .../ActionDeleteResultFilenames.java               |  12 -
 .../hop/workflow/actions/eval/ActionEval.java      |  10 -
 .../evalfilesmetrics/ActionEvalFilesMetrics.java   |  28 ---
 .../actions/filecompare/ActionFileCompare.java     |  12 -
 .../actions/fileexists/ActionFileExists.java       |  10 -
 .../actions/filesexist/ActionFilesExist.java       |  11 -
 .../actions/folderisempty/ActionFolderIsEmpty.java |  13 --
 .../folderscompare/ActionFoldersCompare.java       |  16 --
 .../hop/workflow/actions/join/ActionJoin.java      |   5 -
 .../actions/movefiles/ActionMoveFiles.java         |  41 ----
 .../pgpdecryptfiles/ActionPGPDecryptFiles.java     |  42 ----
 .../actions/pgpverify/ActionPGPVerify.java         |  13 --
 .../hop/workflow/actions/ping/ActionPing.java      |   6 -
 .../hop/workflow/actions/repeat/EndRepeat.java     |   5 -
 .../apache/hop/workflow/actions/repeat/Repeat.java |   5 -
 .../ActionSendNagiosPassiveCheck.java              |   6 -
 .../ActionSetPasswordEncoder.java                  |  12 -
 .../actions/setvariables/ActionSetVariables.java   |  13 --
 .../actions/simpleeval/ActionSimpleEval.java       |   6 -
 .../apache/hop/workflow/actions/sql/ActionSql.java |   6 -
 .../workflow/actions/success/ActionSuccess.java    |   6 -
 .../actions/tableexists/ActionTableExists.java     |   6 -
 .../hop/workflow/actions/telnet/ActionTelnet.java  |   6 -
 .../hop/workflow/actions/unzip/ActionUnZip.java    |   6 -
 .../actions/waitforfile/ActionWaitForFile.java     |   6 -
 .../actions/waitforsql/ActionWaitForSql.java       |   5 -
 .../ActionWebServiceAvailable.java                 |   6 -
 .../actions/writetofile/ActionWriteToFile.java     |   6 -
 .../actions/writetolog/ActionWriteToLog.java       |   6 -
 .../actions/xml/dtdvalidator/DtdValidator.java     |   6 -
 .../actions/xml/xmlwellformed/XmlWellFormed.java   |   6 -
 .../actions/xml/xsdvalidator/XsdValidator.java     |   6 -
 .../workflow/actions/zipfile/ActionZipFile.java    |   6 -
 .../transforms/accessoutput/AccessOutputMeta.java  |   6 -
 .../actions/as400command/ActionAs400Command.java   |  15 --
 .../cratedbbulkloader/CrateDBBulkLoaderMeta.java   |   5 -
 .../bulkloader/SnowflakeBulkLoaderMeta.java        |  10 -
 .../actions/snowflake/WarehouseManager.java        |   5 -
 .../pipeline/transforms/terafast/TeraFastMeta.java |  10 -
 .../vertica/bulkloader/VerticaBulkLoaderMeta.java  |   5 -
 .../bigtable/BeamBigtableOutputMeta.java           |  16 --
 .../org/apache/hop/documentation/ActionDoc.java    |  15 --
 .../mail/pipeline/transforms/mail/MailMeta.java    |  57 -----
 .../transforms/mailinput/MailInputMeta.java        |  14 --
 .../mail/workflow/actions/getpop/ActionGetPOP.java |   6 -
 .../hop/mail/workflow/actions/mail/ActionMail.java |  10 -
 .../testing/actions/runtests/RunPipelineTests.java |   5 -
 .../transforms/avroinput/AvroFileInputMeta.java    |  11 -
 .../avro/transforms/avrooutput/AvroOutputMeta.java |  11 -
 .../pipeline/transforms/aws/sns/SnsNotifyMeta.java |  16 --
 .../pipeline/transforms/aws/sqs/SqsReaderMeta.java |  16 --
 .../bulkloader/RedshiftBulkLoaderMeta.java         |   5 -
 .../eventhubs/listen/AzureListenerMeta.java        |  28 ---
 .../eventhubs/write/AzureWriterMeta.java           |  14 --
 .../actions/databricks/ActionDatabricksJobRun.java |   5 -
 .../databricks/ActionDatabricksJobWait.java        |   5 -
 .../actions/ftpdelete/ActionFtpDelete.java         |   5 -
 .../hop/workflow/actions/ftpput/ActionFtpPut.java  |   6 -
 .../googlesheets/GoogleSheetsOutputMeta.java       |  15 --
 .../transforms/mongodbinput/MongoDbInputMeta.java  |   6 -
 .../apache/hop/workflow/actions/mql/ActionMql.java |   6 -
 .../neo4j/actions/cypherscript/CypherScript.java   |  12 -
 .../hop/neo4j/transforms/cypher/CypherMeta.java    |  23 --
 .../cypherbuilder/CypherBuilderDialog.java         |   2 +-
 .../cypherbuilder/CypherBuilderMeta.java           |  15 --
 .../transforms/loginfo/GetLoggingInfoMeta.java     |   7 -
 .../neo4j/transforms/output/Neo4JOutputMeta.java   |   5 -
 .../salesforce/SalesforceTransformMeta.java        |   6 -
 .../salesforcedelete/SalesforceDeleteMeta.java     |   7 -
 .../salesforceinput/SalesforceInputMeta.java       |  19 --
 .../salesforceinsert/SalesforceInsertMeta.java     |  15 --
 .../salesforceupdate/SalesforceUpdateMeta.java     |  17 --
 .../salesforceupsert/SalesforceUpsertMeta.java     |  16 --
 .../hop/workflow/actions/sftp/ActionSftp.java      |  31 ---
 .../workflow/actions/sftpput/ActionSftpPut.java    |   5 -
 .../binaryfileoutput/BinaryFileOutputMeta.java     |   5 -
 .../BlockUntilTransformsFinishMeta.java            |   9 -
 .../transforms/calculator/CalculatorDialog.java    |   2 +-
 .../transforms/calculator/CalculatorMeta.java      |  12 -
 .../changefileencoding/ChangeFileEncodingMeta.java |   7 -
 .../pipeline/transforms/checksum/CheckSumMeta.java |  15 --
 .../transforms/closure/ClosureGeneratorMeta.java   |  12 -
 .../pipeline/transforms/coalesce/CoalesceMeta.java |  13 --
 .../transforms/columnexists/ColumnExistsMeta.java  |   7 -
 .../combinationlookup/CombinationLookupMeta.java   |  10 -
 .../transforms/concatfields/ConcatFieldsMeta.java  |  10 -
 .../pipeline/transforms/constant/ConstantMeta.java |   5 -
 .../constant/ConstantChangeDetectionTest.java      |  77 +++++++
 .../CreditCardValidatorMeta.java                   |  13 --
 .../transforms/cubeinput/CubeInputMeta.java        |  12 -
 .../transforms/cubeoutput/CubeOutputMeta.java      |  12 -
 .../transforms/databasejoin/DatabaseJoinMeta.java  |  20 --
 .../databaselookup/DatabaseLookupMeta.java         |  13 --
 .../databaselookup/DatabaseLookupMetaTest.java     |   2 +-
 .../transforms/datagrid/DataGridDialog.java        |   2 +-
 .../pipeline/transforms/datagrid/DataGridMeta.java |  11 -
 .../datagrid/DataGridChangeDetectionTest.java      | 111 ++++++++++
 .../dbimpact/input/DbImpactInputMeta.java          |  10 -
 .../hop/pipeline/transforms/dbproc/DBProcMeta.java |  16 --
 .../hop/pipeline/transforms/delay/DelayMeta.java   |   5 -
 .../hop/pipeline/transforms/delete/DeleteMeta.java |   5 -
 .../transforms/denormaliser/DenormaliserMeta.java  |  16 --
 .../detectemptystream/DetectEmptyStreamMeta.java   |   6 -
 .../detectlastrow/DetectLastRowMeta.java           |   7 -
 .../dimensionlookup/DimensionLookupMeta.java       |  27 ---
 .../dynamicsqlrow/DynamicSqlRowMeta.java           |   5 -
 .../pipeline/transforms/edi2xml/Edi2XmlMeta.java   |  11 -
 .../transforms/excelinput/ExcelInputMeta.java      |  46 ----
 .../excelwriter/ExcelWriterTransformMeta.java      |   5 -
 .../transforms/excelinput/ExcelInputMetaTest.java  |   2 +-
 .../pipeline/transforms/execinfo/ExecInfoMeta.java |  16 --
 .../transforms/execprocess/ExecProcessMeta.java    |   5 -
 .../execprocess/ExecProcessMetaTest.java           |   2 +-
 .../transforms/execsqlrow/ExecSqlRowMeta.java      |   5 -
 .../hop/pipeline/transforms/fake/FakeMeta.java     |  11 -
 .../hop/pipeline/transforms/fake/FakeMetaTest.java |   2 +-
 .../FieldsChangeSequenceMeta.java                  |  17 --
 .../fieldsplitter/FieldSplitterMeta.java           |  15 --
 .../transforms/fileexists/FileExistsMeta.java      |   6 -
 .../transforms/filelocked/FileLockedMeta.java      |   7 -
 .../transforms/filemetadata/FileMetadataMeta.java  |  21 --
 .../filesfromresult/FilesFromResultMeta.java       |   6 -
 .../filestoresult/FilesToResultMeta.java           |  10 -
 .../transforms/flattener/FlattenerMeta.java        |  11 -
 .../pipeline/transforms/formula/FormulaMeta.java   |   5 -
 .../transforms/formula/FormulaMetaTest.java        |   2 +-
 .../transforms/fuzzymatch/FuzzyMatchMeta.java      |  21 --
 .../transforms/fuzzymatch/FuzzyMatchMetaTest.java  |   2 +-
 .../transforms/getfilenames/GetFileNamesMeta.java  |   5 -
 .../getfilesrowcount/GetFilesRowsCountMeta.java    |  19 --
 .../getsubfolders/GetSubFoldersMeta.java           |  16 --
 .../gettablenames/GetTableNamesMeta.java           |  24 --
 .../transforms/getvariable/GetVariableMeta.java    |  10 -
 .../pipeline/transforms/groupby/GroupByMeta.java   |  19 --
 .../hop/pipeline/transforms/GroupByMetaTest.java   |   2 +-
 .../hop/pipeline/transforms/http/HttpMeta.java     |  23 --
 .../pipeline/transforms/httppost/HttpPostMeta.java |   7 -
 .../hop/pipeline/transforms/ifnull/IfNullMeta.java |  21 --
 .../transforms/insertupdate/InsertUpdateMeta.java  |   7 -
 .../InsertUpdateChangeDetectionTest.java           |  94 ++++++++
 .../insertupdate/InsertUpdateUndoTest.java         |  78 +++++++
 .../hop/pipeline/transforms/janino/JaninoMeta.java |  11 -
 .../transforms/javafilter/JavaFilterMeta.java      |   6 -
 .../UserDefinedJavaClassMeta.java                  |  19 --
 .../UserDefinedJavaClassMetaTest.java              |   2 +-
 .../transforms/javascript/ScriptValuesMeta.java    |  18 --
 .../transforms/jdbcmetadata/JdbcMetadataMeta.java  |  16 --
 .../transforms/jsoninput/JsonInputMeta.java        |  28 ---
 .../jsonnormalize/JsonNormalizeInputMeta.java      |  32 ---
 .../transforms/jsonoutput/JsonOutputMeta.java      |  19 --
 .../jsonoutputenhanced/JsonEOutputMeta.java        |  21 --
 .../kafka/consumer/KafkaConsumerInputDialog.java   |   2 +-
 .../kafka/consumer/KafkaConsumerInputMeta.java     |  30 ---
 .../kafka/consumer/KafkaConsumerInputMetaTest.java |   2 +-
 .../transforms/ldapinput/LdapInputMeta.java        |   9 +-
 .../transforms/ldapoutput/LdapOutputMeta.java      |   9 +-
 .../loadfileinput/LoadFileInputMeta.java           |  23 --
 .../transforms/input/MappingInputMeta.java         |  12 -
 .../transforms/mapping/SimpleMappingMeta.java      |  11 -
 .../transforms/multimapping/MultiMappingMeta.java  |  12 -
 .../transforms/output/MappingOutputMeta.java       |   9 -
 .../transforms/input/MappingInputMetaTest.java     |   2 +-
 .../multimapping/MultiMappingMetaTest.java         |   2 +-
 .../transforms/memgroupby/MemoryGroupByMeta.java   |  16 --
 .../transforms/mergejoin/MergeJoinMeta.java        |  13 --
 .../transforms/mergerows/MergeRowsMeta.java        |  17 --
 .../transforms/mergerows/MergeRowsMetaTest.java    |   2 +-
 .../transforms/metainput/MetadataInputMeta.java    |  16 --
 .../transforms/metainject/MetaInjectMeta.java      |  20 --
 .../metastructure/TransformMetaStructureMeta.java  |   5 -
 .../transforms/normaliser/NormaliserMeta.java      |  12 -
 .../hop/pipeline/transforms/nullif/NullIfMeta.java |  12 -
 .../transforms/numberrange/NumberRangeMeta.java    |   6 -
 .../pipeline/transforms/odata/ODataInputMeta.java  |  20 --
 .../pgpdecryptstream/PGPDecryptStreamMeta.java     |  15 --
 .../pgpencryptstream/PGPEncryptStreamMeta.java     |  15 --
 .../propertyinput/PropertyInputMeta.java           |  34 ---
 .../propertyoutput/PropertyOutputMeta.java         |  15 --
 .../transforms/randomvalue/RandomValueMeta.java    |   5 -
 .../randomvalue/RandomValueMetaTest.java           |   2 +-
 .../transforms/regexeval/RegexEvalMeta.java        |  23 --
 .../transforms/repeatfields/RepeatFieldsMeta.java  |  13 --
 .../replacestring/ReplaceStringMeta.java           |  10 -
 .../reservoirsampling/ReservoirSamplingMeta.java   |  16 --
 .../hop/pipeline/transforms/rest/RestMeta.java     |   7 -
 .../transforms/rowgenerator/RowGeneratorMeta.java  |  17 --
 .../rowsfromresult/RowsFromResultMeta.java         |  10 -
 .../transforms/rowstoresult/RowsToResultMeta.java  |   6 -
 .../transforms/samplerows/SampleRowsMeta.java      |   6 -
 .../pipeline/transforms/sasinput/SasInputMeta.java |  15 --
 .../hop/pipeline/transforms/script/ScriptMeta.java |  12 -
 .../pipeline/transforms/script/ScriptMetaTest.java |   2 +-
 .../transforms/selectvalues/SelectValuesMeta.java  |  10 -
 .../serverstatus/GetServerStatusMeta.java          |  25 ---
 .../setvaluefield/SetValueFieldMeta.java           |  12 -
 .../hop/pipeline/transforms/sort/SortRowsMeta.java |  17 --
 .../transforms/sortedmerge/SortedMergeMeta.java    |  10 -
 .../hop/pipeline/transforms/sql/ExecSqlMeta.java   |   6 -
 .../StandardizePhoneNumberMeta.java                |  13 --
 .../transforms/streamlookup/StreamLookupMeta.java  |   5 -
 .../streamschemamerge/StreamSchemaMeta.java        |  19 --
 .../transforms/stringcut/StringCutMeta.java        |  12 -
 .../stringoperations/StringOperationsMeta.java     |  10 -
 .../surefirereport/SurefireReportOutputMeta.java   |   5 -
 .../transforms/switchcase/SwitchCaseMeta.java      |  19 --
 .../SynchronizeAfterMergeMeta.java                 |  19 --
 .../transforms/systemdata/SystemDataMeta.java      |   5 -
 .../transforms/tableinput/TableInputMeta.java      |  16 --
 .../transforms/tableoutput/TableOutputMeta.java    |   5 -
 .../TableOutputChangeDetectionTest.java            |  68 ++++++
 .../pipeline/transforms/csvinput/CsvInputMeta.java |  34 +--
 .../fileinput/text/TextFileInputMeta.java          |  21 +-
 .../textfileoutput/TextFileOutputMeta.java         |  29 ---
 .../hop/pipeline/transforms/tika/TikaMeta.java     |  31 ---
 .../tokenreplacement/TokenReplacementMeta.java     |  36 ---
 .../transforms/uniquerows/UniqueRowsMeta.java      |   5 -
 .../UniqueRowsByHashSetMeta.java                   |  13 --
 .../hop/pipeline/transforms/update/UpdateMeta.java |   6 -
 .../update/UpdateChangeDetectionTest.java          |  88 ++++++++
 .../transforms/validator/ValidatorMeta.java        |  15 --
 .../transforms/validator/ValidatorMetaTest.java    |   2 +-
 .../transforms/webservices/WebServiceMeta.java     |  28 ---
 .../transforms/writetolog/WriteToLogMeta.java      |   7 -
 .../pipeline/transforms/xml/addxml/AddXmlMeta.java |  14 --
 .../xml/xmlinputstream/XmlInputStreamMeta.java     |  45 ----
 .../transforms/xml/xmljoin/XmlJoinMeta.java        |  20 --
 .../transforms/xml/xmloutput/XmlOutputMeta.java    |  15 --
 .../xml/xsdvalidator/XsdValidatorMeta.java         |  21 --
 .../hop/pipeline/transforms/xml/xslt/XsltMeta.java |  18 --
 .../transforms/yamlinput/YamlInputMeta.java        |  24 --
 .../transforms/yamlinput/YamlInputMetaTest.java    |   2 +-
 .../pipeline/transforms/zipfile/ZipFileMeta.java   |   7 -
 252 files changed, 1226 insertions(+), 2931 deletions(-)

diff --git a/core/src/main/java/org/apache/hop/metadata/util/HopMetadataCopyUtil.java b/core/src/main/java/org/apache/hop/metadata/util/HopMetadataCopyUtil.java
new file mode 100644
index 0000000000..45283d0a65
--- /dev/null
+++ b/core/src/main/java/org/apache/hop/metadata/util/HopMetadataCopyUtil.java
@@ -0,0 +1,243 @@
+/*
+ * 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
+ *
+ *       http://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.hop.metadata.util;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.logging.LogChannel;
+import org.apache.hop.metadata.api.HopMetadataProperty;
+import org.apache.hop.metadata.api.IHopMetadata;
+
+/**
+ * Deep-copies the state that Hop persists, driven by the {@link HopMetadataProperty} annotations.
+ *
+ * <p>{@code Object.clone()} is shallow, so a cloned metadata object keeps sharing every list, map
+ * and nested value object with the original. That is invisible most of the time, but it breaks the
+ * two places where a metadata snapshot has to be independent of the live object: deciding whether a
+ * dialog changed anything, and rolling an edit back through undo. See issue #8022.
+ *
+ * <p>The annotations describe exactly the state that ends up in the .hpl / .hwf file, which is
+ * precisely the state those two features compare and restore. Everything else - live references to
+ * other transforms, metadata providers, caches - is left shared, which is the deliberate behaviour
+ * documented on {@code BaseTransformMeta.clone()}.
+ */
+public final class HopMetadataCopyUtil {
+
+  private static final ILogChannel log = new LogChannel("HopMetadataCopyUtil");
+
+  private HopMetadataCopyUtil() {
+    // Utility class
+  }
+
+  /**
+   * Deep-copies every serializable property of {@code source} into {@code target}, leaving all
+   * other fields of {@code target} untouched.
+   *
+   * <p>Call this right after {@code super.clone()} to turn a shallow copy into one whose persisted
+   * state is independent of the original.
+   *
+   * @param source The object to copy the properties from
+   * @param target The object to copy the properties into, usually a shallow clone of the source
+   */
+  public static void copyMetadataProperties(Object source, Object target) {
+    if (source == null || target == null) {
+      return;
+    }
+    copyProperties(source, target, new IdentityHashMap<>());
+  }
+
+  /**
+   * Creates an independent copy of a single value using the same rules as {@link
+   * #copyMetadataProperties(Object, Object)}.
+   *
+   * @param value The value to copy, may be null
+   * @return An independent copy, or the value itself when it is immutable or cannot be copied
+   */
+  public static Object copyValue(Object value) {
+    return copyValue(value, new IdentityHashMap<>());
+  }
+
+  private static void copyProperties(
+      Object source, Object target, IdentityHashMap<Object, Object> seen) {
+    for (Field field : ReflectionUtil.findAllFields(source.getClass())) {
+      if (!isSerializableProperty(field)) {
+        continue;
+      }
+      try {
+        field.setAccessible(true);
+        Object value = field.get(source);
+        // A property stored by name references a shared, named metadata object. The file only
+        // holds its name, so the reference is shared rather than copied.
+        HopMetadataProperty property = field.getAnnotation(HopMetadataProperty.class);
+        field.set(target, property.storeWithName() ? value : copyValue(value, seen));
+      } catch (Exception e) {
+        // Leave the shallow value in place: a partial copy is still better than a failed clone.
+        log.logError(
+            "Unable to copy property '"
+                + field.getName()
+                + "' of "
+                + source.getClass().getName()
+                + ", it stays shared with the original",
+            e);
+      }
+    }
+  }
+
+  private static Object copyValue(Object value, IdentityHashMap<Object, Object> seen) {
+    if (value == null || isImmutable(value)) {
+      return value;
+    }
+
+    Object known = seen.get(value);
+    if (known != null) {
+      return known;
+    }
+
+    if (value instanceof Date date) {
+      return new Date(date.getTime());
+    }
+    if (value instanceof IHopMetadata) {
+      // Named metadata lives in the metadata store, not in the object referencing it. The file
+      // only carries a reference, so a snapshot shares it rather than duplicating it.
+      return value;
+    }
+    if (value instanceof Map<?, ?> map) {
+      return copyMap(map, seen);
+    }
+    if (value instanceof Collection<?> collection) {
+      return copyCollection(collection, seen);
+    }
+    if (value.getClass().isArray()) {
+      return copyArray(value, seen);
+    }
+    return copyObject(value, seen);
+  }
+
+  private static boolean isImmutable(Object value) {
+    return value instanceof String
+        || value instanceof Number
+        || value instanceof Boolean
+        || value instanceof Character
+        || value instanceof Class
+        || value.getClass().isEnum();
+  }
+
+  private static Object copyMap(Map<?, ?> map, IdentityHashMap<Object, Object> seen) {
+    Map<Object, Object> copy = newInstanceOr(map.getClass(), LinkedHashMap::new);
+    seen.put(map, copy);
+    for (Map.Entry<?, ?> entry : map.entrySet()) {
+      copy.put(copyValue(entry.getKey(), seen), copyValue(entry.getValue(), seen));
+    }
+    return copy;
+  }
+
+  private static Object copyCollection(
+      Collection<?> collection, IdentityHashMap<Object, Object> seen) {
+    Collection<Object> copy =
+        collection instanceof Set
+            ? newInstanceOr(collection.getClass(), LinkedHashSet::new)
+            : newInstanceOr(collection.getClass(), ArrayList::new);
+    seen.put(collection, copy);
+    for (Object item : collection) {
+      copy.add(copyValue(item, seen));
+    }
+    return copy;
+  }
+
+  private static Object copyArray(Object array, IdentityHashMap<Object, Object> seen) {
+    int length = Array.getLength(array);
+    Object copy = Array.newInstance(array.getClass().getComponentType(), length);
+    seen.put(array, copy);
+    for (int i = 0; i < length; i++) {
+      Array.set(copy, i, copyValue(Array.get(array, i), seen));
+    }
+    return copy;
+  }
+
+  /**
+   * Copies a value object: a new instance holding a deep copy of its serializable properties and a
+   * shared reference to everything else, mirroring what {@code super.clone()} does one level up.
+   */
+  private static Object copyObject(Object source, IdentityHashMap<Object, Object> seen) {
+    Class<?> sourceClass = source.getClass();
+    Object copy;
+    try {
+      Constructor<?> constructor = sourceClass.getDeclaredConstructor();
+      constructor.setAccessible(true);
+      copy = constructor.newInstance();
+    } catch (Exception e) {
+      // No usable no-argument constructor: share the reference, which is the behaviour we had
+      // before this method existed.
+      log.logDebug(
+          "No no-argument constructor on "
+              + sourceClass.getName()
+              + ", the value stays shared with the original");
+      return source;
+    }
+
+    seen.put(source, copy);
+    for (Field field : ReflectionUtil.findAllFields(sourceClass)) {
+      if (Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) {
+        continue;
+      }
+      try {
+        field.setAccessible(true);
+        Object value = field.get(source);
+        field.set(copy, value);
+      } catch (Exception e) {
+        log.logDebug(
+            "Unable to copy field '" + field.getName() + "' of " + sourceClass.getName(), e);
+      }
+    }
+    copyProperties(source, copy, seen);
+    return copy;
+  }
+
+  private static boolean isSerializableProperty(Field field) {
+    int modifiers = field.getModifiers();
+    // Transient and volatile fields are skipped by the XML serializer as well, so they are not
+    // part of the persisted state and stay shared.
+    if (Modifier.isStatic(modifiers)
+        || Modifier.isTransient(modifiers)
+        || Modifier.isVolatile(modifiers)) {
+      return false;
+    }
+    return field.getAnnotation(HopMetadataProperty.class) != null;
+  }
+
+  @SuppressWarnings("unchecked")
+  private static <T> T newInstanceOr(Class<?> clazz, java.util.function.Supplier<T> fallback) {
+    try {
+      return (T) clazz.getDeclaredConstructor().newInstance();
+    } catch (Exception e) {
+      // Immutable or otherwise non-instantiable containers such as List.of() land here.
+      return fallback.get();
+    }
+  }
+}
diff --git a/core/src/test/java/org/apache/hop/metadata/util/HopMetadataCopyUtilTest.java b/core/src/test/java/org/apache/hop/metadata/util/HopMetadataCopyUtilTest.java
new file mode 100644
index 0000000000..e7a45200a8
--- /dev/null
+++ b/core/src/test/java/org/apache/hop/metadata/util/HopMetadataCopyUtilTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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
+ *
+ *       http://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.hop.metadata.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.hop.metadata.api.HopMetadataProperty;
+import org.junit.jupiter.api.Test;
+
+class HopMetadataCopyUtilTest {
+
+  public static class Item {
+    @HopMetadataProperty private String name;
+
+    public Item() {}
+
+    public Item(String name) {
+      this.name = name;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public void setName(String name) {
+      this.name = name;
+    }
+  }
+
+  public static class Nested {
+    @HopMetadataProperty private String table;
+    @HopMetadataProperty private List<Item> items = new ArrayList<>();
+
+    public String getTable() {
+      return table;
+    }
+
+    public void setTable(String table) {
+      this.table = table;
+    }
+
+    public List<Item> getItems() {
+      return items;
+    }
+  }
+
+  public static class Holder {
+    @HopMetadataProperty private String plain;
+    @HopMetadataProperty private List<Item> items = new ArrayList<>();
+    @HopMetadataProperty private Map<String, Item> byName = new LinkedHashMap<>();
+    @HopMetadataProperty private Nested nested = new Nested();
+    @HopMetadataProperty private Date date;
+    @HopMetadataProperty private String[] tags;
+    @HopMetadataProperty private Nested absent;
+
+    // Not annotated: a live reference that must keep being shared.
+    private Object liveReference;
+    // Transient state is not persisted either, so it stays shared.
+    @HopMetadataProperty private transient Object cache;
+  }
+
+  private static Holder populated() {
+    Holder holder = new Holder();
+    holder.plain = "original";
+    holder.items.add(new Item("one"));
+    holder.byName.put("a", new Item("a"));
+    holder.nested.setTable("customers");
+    holder.nested.getItems().add(new Item("nested-one"));
+    holder.date = new Date(1_000_000L);
+    holder.tags = new String[] {"x", "y"};
+    holder.liveReference = new Object();
+    holder.cache = new Object();
+    return holder;
+  }
+
+  private static Holder copyOf(Holder source) {
+    Holder target = new Holder();
+    // Mimic Object.clone(): every field starts out shared with the source.
+    target.plain = source.plain;
+    target.items = source.items;
+    target.byName = source.byName;
+    target.nested = source.nested;
+    target.date = source.date;
+    target.tags = source.tags;
+    target.absent = source.absent;
+    target.liveReference = source.liveReference;
+    target.cache = source.cache;
+
+    HopMetadataCopyUtil.copyMetadataProperties(source, target);
+    return target;
+  }
+
+  @Test
+  void listsAreIndependent() {
+    Holder source = populated();
+    Holder copy = copyOf(source);
+
+    assertNotSame(source.items, copy.items);
+    assertNotSame(source.items.get(0), copy.items.get(0));
+
+    source.items.clear();
+    source.items.add(new Item("replaced"));
+
+    assertEquals(1, copy.items.size());
+    assertEquals("one", copy.items.get(0).getName());
+  }
+
+  @Test
+  void nestedObjectsAreIndependent() {
+    Holder source = populated();
+    Holder copy = copyOf(source);
+
+    assertNotSame(source.nested, copy.nested);
+    source.nested.setTable("orders");
+    source.nested.getItems().get(0).setName("changed");
+
+    assertEquals("customers", copy.nested.getTable());
+    assertEquals("nested-one", copy.nested.getItems().get(0).getName());
+  }
+
+  @Test
+  void mapsArraysAndDatesAreIndependent() {
+    Holder source = populated();
+    Holder copy = copyOf(source);
+
+    assertNotSame(source.byName, copy.byName);
+    assertNotSame(source.byName.get("a"), copy.byName.get("a"));
+    assertNotSame(source.tags, copy.tags);
+    assertNotSame(source.date, copy.date);
+    assertEquals(source.date, copy.date);
+
+    source.byName.get("a").setName("changed");
+    source.tags[0] = "changed";
+    source.date.setTime(42L);
+
+    assertEquals("a", copy.byName.get("a").getName());
+    assertEquals("x", copy.tags[0]);
+    assertEquals(1_000_000L, copy.date.getTime());
+  }
+
+  @Test
+  void unannotatedAndTransientStateStaysShared() {
+    Holder source = populated();
+    Holder copy = copyOf(source);
+
+    assertSame(source.liveReference, copy.liveReference);
+    assertSame(source.cache, copy.cache);
+  }
+
+  @Test
+  void nullPropertiesStayNull() {
+    Holder source = populated();
+    Holder copy = copyOf(source);
+
+    assertNull(copy.absent);
+  }
+}
diff --git a/engine/src/main/java/org/apache/hop/pipeline/transform/BaseTransformMeta.java b/engine/src/main/java/org/apache/hop/pipeline/transform/BaseTransformMeta.java
index ac18acafcc..6e5612592e 100644
--- a/engine/src/main/java/org/apache/hop/pipeline/transform/BaseTransformMeta.java
+++ b/engine/src/main/java/org/apache/hop/pipeline/transform/BaseTransformMeta.java
@@ -52,6 +52,7 @@ import org.apache.hop.core.security.Permission;
 import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.metadata.serializer.xml.XmlMetadataUtil;
+import org.apache.hop.metadata.util.HopMetadataCopyUtil;
 import org.apache.hop.pipeline.DatabaseImpact;
 import org.apache.hop.pipeline.Pipeline;
 import org.apache.hop.pipeline.PipelineMeta;
@@ -225,6 +226,13 @@ public class BaseTransformMeta<Main extends ITransform, Data extends ITransformD
       } finally {
         lock.readLock().unlock();
       }
+
+      // Object.clone() is shallow, so every list, map and nested value object is still shared with
+      // the original. Deep-copy the state that gets persisted so the copy can be used as an
+      // independent snapshot, for change detection and for undo. Fixes issue #8022.
+      //
+      HopMetadataCopyUtil.copyMetadataProperties(this, retval);
+
       return retval;
     } catch (CloneNotSupportedException e) {
       return null;
diff --git a/engine/src/main/java/org/apache/hop/pipeline/transform/TransformMeta.java b/engine/src/main/java/org/apache/hop/pipeline/transform/TransformMeta.java
index 735bc4d3ec..fe38032ecd 100644
--- a/engine/src/main/java/org/apache/hop/pipeline/transform/TransformMeta.java
+++ b/engine/src/main/java/org/apache/hop/pipeline/transform/TransformMeta.java
@@ -72,6 +72,15 @@ public class TransformMeta
         IHasName {
   private static final Class<?> PKG = TransformMeta.class;
 
+  /**
+   * Tracks changes to the settings this wrapper owns - position, number of copies, row distribution
+   * - as opposed to the settings a transform dialog edits, which live on the inner {@link
+   * ITransformMeta}. Keeping the two apart means a dialog's Cancel, which restores the inner flag
+   * it captured when it opened, cannot discard a change made on the canvas in the meantime.
+   * Transform dialogs are not modal, so that overlap is easy to hit. See issue #8022.
+   */
+  private boolean wrapperChanged;
+
   public static final String XML_TAG = "transform";
   public static final String STRING_ID_MAPPING = "Mapping";
   public static final String STRING_ID_SINGLE_THREADER = "SingleThreader";
@@ -352,7 +361,7 @@ public class TransformMeta
    * @param c The number of copies.
    */
   public void setCopies(int c) {
-    setChanged();
+    setWrapperChanged();
     copiesString = Integer.toString(c);
     copiesCache = c;
   }
@@ -419,10 +428,11 @@ public class TransformMeta
   public synchronized boolean hasChanged() {
     // Check both the wrapper level changed flag and the inner metadata
     ITransformMeta meta = this.getTransform();
-    return meta != null && meta.hasChanged();
+    return wrapperChanged || (meta != null && meta.hasChanged());
   }
 
   public synchronized void setChanged(boolean ch) {
+    wrapperChanged = ch;
     // Propagate to inner metadata
     ITransformMeta meta = this.getTransform();
     if (meta != null) {
@@ -434,6 +444,14 @@ public class TransformMeta
     setChanged(true);
   }
 
+  /**
+   * Marks the settings owned by this wrapper as changed, without touching the transform's own
+   * changed flag. See {@link #wrapperChanged}.
+   */
+  private synchronized void setWrapperChanged() {
+    wrapperChanged = true;
+  }
+
   public boolean chosesTargetTransforms() {
     if (getTransform() != null) {
       List<IStream> targetStreams = getTransform().getTransformIOMeta().getTargetStreams();
@@ -539,7 +557,7 @@ public class TransformMeta
 
     Point loc = new Point(nx, ny);
     if (!loc.equals(location)) {
-      setChanged();
+      setWrapperChanged();
     }
     location = loc;
   }
@@ -547,7 +565,7 @@ public class TransformMeta
   @Override
   public void setLocation(Point loc) {
     if (loc != null && !loc.equals(location)) {
-      setChanged();
+      setWrapperChanged();
     }
     location = loc;
   }
@@ -594,7 +612,7 @@ public class TransformMeta
   public void setDistributes(boolean distributes) {
     if (this.distributes != distributes) {
       this.distributes = distributes;
-      setChanged();
+      setWrapperChanged();
     }
   }
 
@@ -732,7 +750,7 @@ public class TransformMeta
     if (rowDistribution != null) {
       setDistributes(true);
     }
-    setChanged();
+    setWrapperChanged();
   }
 
   /**
diff --git a/engine/src/main/java/org/apache/hop/workflow/action/ActionBase.java b/engine/src/main/java/org/apache/hop/workflow/action/ActionBase.java
index 07cbed4874..a38033a02f 100644
--- a/engine/src/main/java/org/apache/hop/workflow/action/ActionBase.java
+++ b/engine/src/main/java/org/apache/hop/workflow/action/ActionBase.java
@@ -59,6 +59,7 @@ import org.apache.hop.core.xml.XmlHandler;
 import org.apache.hop.metadata.api.HopMetadataProperty;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.metadata.serializer.xml.XmlMetadataUtil;
+import org.apache.hop.metadata.util.HopMetadataCopyUtil;
 import org.apache.hop.resource.IResourceHolder;
 import org.apache.hop.resource.IResourceNaming;
 import org.apache.hop.resource.ResourceDefinition;
@@ -421,6 +422,13 @@ public abstract class ActionBase
     } catch (CloneNotSupportedException cnse) {
       return null;
     }
+
+    // Object.clone() is shallow, so every list, map and nested value object is still shared with
+    // the original. Deep-copy the state that gets persisted so the copy can be used as an
+    // independent snapshot, for change detection and for undo. Fixes issue #8022.
+    //
+    HopMetadataCopyUtil.copyMetadataProperties(this, je);
+
     return je;
   }
 
diff --git a/engine/src/main/java/org/apache/hop/workflow/action/ActionMeta.java b/engine/src/main/java/org/apache/hop/workflow/action/ActionMeta.java
index f3ad7d8553..6ef2c775f4 100644
--- a/engine/src/main/java/org/apache/hop/workflow/action/ActionMeta.java
+++ b/engine/src/main/java/org/apache/hop/workflow/action/ActionMeta.java
@@ -56,6 +56,15 @@ public class ActionMeta
   private static final String XML_ATTRIBUTE_WORKFLOW_ACTION_COPY = AttributesUtil.XML_TAG + "_hac";
   private static final String CONST_SPACE = "      ";
 
+  /**
+   * Tracks changes to the settings this wrapper owns - the position on the canvas - as opposed to
+   * the settings an action dialog edits, which live on the {@link IAction} itself. Keeping the two
+   * apart means a dialog's Cancel, which restores the action's flag as it was when the dialog
+   * opened, cannot discard a change made on the canvas in the meantime. Action dialogs are not
+   * modal, so that overlap is easy to hit. See issue #8022.
+   */
+  private boolean wrapperChanged;
+
   @HopMetadataProperty(inline = true)
   private IAction action;
 
@@ -278,7 +287,7 @@ public class ActionMeta
 
     Point loc = new Point(nx, ny);
     if (!loc.equals(location)) {
-      setChanged();
+      setWrapperChanged();
     }
     location = loc;
   }
@@ -286,7 +295,7 @@ public class ActionMeta
   @Override
   public void setLocation(Point loc) {
     if (loc != null && !loc.equals(location)) {
-      setChanged();
+      setWrapperChanged();
     }
     location = loc;
   }
@@ -304,17 +313,27 @@ public class ActionMeta
   @SuppressWarnings("javabugs:S2259") // the action is set by every constructor
   @Override
   public void setChanged(boolean ch) {
+    wrapperChanged = ch;
     action.setChanged(ch);
   }
 
   @Override
   public void clearChanged() {
+    wrapperChanged = false;
     action.setChanged(false);
   }
 
   @Override
   public boolean hasChanged() {
-    return action.hasChanged();
+    return wrapperChanged || action.hasChanged();
+  }
+
+  /**
+   * Marks the settings owned by this wrapper as changed, without touching the action's own changed
+   * flag. See {@link #wrapperChanged}.
+   */
+  private void setWrapperChanged() {
+    wrapperChanged = true;
   }
 
   public void setLaunchingInParallel(boolean p) {
diff --git a/engine/src/test/java/org/apache/hop/pipeline/transform/TransformMetaChangedFlagTest.java b/engine/src/test/java/org/apache/hop/pipeline/transform/TransformMetaChangedFlagTest.java
new file mode 100644
index 0000000000..26fb7aa4b5
--- /dev/null
+++ b/engine/src/test/java/org/apache/hop/pipeline/transform/TransformMetaChangedFlagTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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
+ *
+ *      http://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.hop.pipeline.transform;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hop.core.gui.Point;
+import org.apache.hop.pipeline.transform.transforms.FakeMeta;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Transform dialogs are not modal, so the canvas stays live while one is open. Every dialog
+ * captures {@code changed = input.hasChanged()} when it is constructed and restores it in cancel(),
+ * which used to wipe anything the canvas had done to the same flag in the meantime. Issue #8022.
+ *
+ * <p>The wrapper now keeps its own flag for the state it owns, so a dialog's Cancel can only roll
+ * back the transform's own settings.
+ */
+class TransformMetaChangedFlagTest {
+
+  private static TransformMeta cleanTransform() {
+    TransformMeta transformMeta = new TransformMeta("T1", new FakeMeta());
+    transformMeta.setLocation(new Point(100, 100));
+    transformMeta.setChanged(false);
+    return transformMeta;
+  }
+
+  @Test
+  void cancelKeepsACanvasMoveMadeWhileTheDialogWasOpen() {
+    TransformMeta transformMeta = cleanTransform();
+    ITransformMeta input = transformMeta.getTransform();
+
+    // The dialog is constructed and captures the flag as it finds it.
+    boolean changed = input.hasChanged();
+
+    // The user drags the transform on the canvas while the dialog is still open.
+    transformMeta.setLocation(new Point(400, 250));
+    assertTrue(transformMeta.hasChanged(), "moving a transform marks it changed");
+
+    // The user goes back to the dialog and presses Cancel.
+    input.setChanged(changed);
+
+    assertTrue(transformMeta.hasChanged(), "Cancel must not discard the move");
+  }
+
+  @Test
+  void cancelStillRollsBackTheDialogsOwnEditing() {
+    TransformMeta transformMeta = cleanTransform();
+    ITransformMeta input = transformMeta.getTransform();
+
+    boolean changed = input.hasChanged();
+
+    // Typing in a dialog field marks the transform's own settings as changed.
+    input.setChanged();
+    assertTrue(transformMeta.hasChanged());
+
+    input.setChanged(changed);
+
+    assertFalse(transformMeta.hasChanged(), "Cancel rolls back the dialog's own marking");
+  }
+
+  @Test
+  void otherWrapperLevelEditsAlsoSurviveCancel() {
+    TransformMeta transformMeta = cleanTransform();
+    ITransformMeta input = transformMeta.getTransform();
+
+    boolean changed = input.hasChanged();
+
+    // Right-click actions on the canvas change settings the wrapper owns.
+    transformMeta.setCopies(4);
+    transformMeta.setDistributes(false);
+
+    input.setChanged(changed);
+
+    assertTrue(transformMeta.hasChanged(), "copies and distribution are wrapper level state");
+  }
+
+  @Test
+  void clearChangedResetsBothFlags() {
+    TransformMeta transformMeta = cleanTransform();
+    transformMeta.setLocation(new Point(400, 250));
+    transformMeta.getTransform().setChanged();
+    assertTrue(transformMeta.hasChanged());
+
+    // What PipelineMeta.clearChanged() does after a save.
+    transformMeta.setChanged(false);
+
+    assertFalse(transformMeta.hasChanged(), "saving clears the wrapper flag as well");
+  }
+}
diff --git a/engine/src/test/java/org/apache/hop/workflow/action/ActionMetaChangedFlagTest.java b/engine/src/test/java/org/apache/hop/workflow/action/ActionMetaChangedFlagTest.java
new file mode 100644
index 0000000000..5c8878e755
--- /dev/null
+++ b/engine/src/test/java/org/apache/hop/workflow/action/ActionMetaChangedFlagTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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
+ *
+ *      http://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.hop.workflow.action;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hop.core.gui.Point;
+import org.apache.hop.workflow.actions.ActionFake;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The action side of issue #8022: action dialogs are not modal either, and they use the same
+ * "capture the flag on open, restore it on cancel" idiom as transform dialogs.
+ */
+class ActionMetaChangedFlagTest {
+
+  private static ActionMeta cleanAction() {
+    ActionMeta actionMeta = new ActionMeta(new ActionFake());
+    actionMeta.setLocation(new Point(100, 100));
+    actionMeta.clearChanged();
+    return actionMeta;
+  }
+
+  @Test
+  void cancelKeepsACanvasMoveMadeWhileTheDialogWasOpen() {
+    ActionMeta actionMeta = cleanAction();
+    IAction action = actionMeta.getAction();
+
+    boolean changed = action.hasChanged();
+
+    actionMeta.setLocation(new Point(400, 250));
+    assertTrue(actionMeta.hasChanged(), "moving an action marks it changed");
+
+    action.setChanged(changed);
+
+    assertTrue(actionMeta.hasChanged(), "Cancel must not discard the move");
+  }
+
+  @Test
+  void cancelStillRollsBackTheDialogsOwnEditing() {
+    ActionMeta actionMeta = cleanAction();
+    IAction action = actionMeta.getAction();
+
+    boolean changed = action.hasChanged();
+
+    action.setChanged();
+    assertTrue(actionMeta.hasChanged());
+
+    action.setChanged(changed);
+
+    assertFalse(actionMeta.hasChanged(), "Cancel rolls back the dialog's own marking");
+  }
+
+  @Test
+  void clearChangedResetsBothFlags() {
+    ActionMeta actionMeta = cleanAction();
+    actionMeta.setLocation(new Point(400, 250));
+    actionMeta.getAction().setChanged();
+    assertTrue(actionMeta.hasChanged());
+
+    actionMeta.clearChanged();
+
+    assertFalse(actionMeta.hasChanged(), "saving clears the wrapper flag as well");
+  }
+}
diff --git a/plugins/actions/abort/src/main/java/org/apache/hop/workflow/actions/abort/ActionAbort.java b/plugins/actions/abort/src/main/java/org/apache/hop/workflow/actions/abort/ActionAbort.java
index 7bd1c2f2ee..de1e8da8dd 100644
--- a/plugins/actions/abort/src/main/java/org/apache/hop/workflow/actions/abort/ActionAbort.java
+++ b/plugins/actions/abort/src/main/java/org/apache/hop/workflow/actions/abort/ActionAbort.java
@@ -67,17 +67,6 @@ public class ActionAbort extends ActionBase implements Cloneable, IAction, ILega
     this("", "");
   }
 
-  public ActionAbort(ActionAbort other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.messageAbort = other.messageAbort;
-    this.messageLogLevel = other.messageLogLevel;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionAbort(this);
-  }
-
   /**
    * Backward compatible code.
    *
diff --git a/plugins/actions/addresultfilenames/src/main/java/org/apache/hop/workflow/actions/addresultfilenames/ActionAddResultFilenames.java b/plugins/actions/addresultfilenames/src/main/java/org/apache/hop/workflow/actions/addresultfilenames/ActionAddResultFilenames.java
index 454d2db53d..93aa843920 100644
--- a/plugins/actions/addresultfilenames/src/main/java/org/apache/hop/workflow/actions/addresultfilenames/ActionAddResultFilenames.java
+++ b/plugins/actions/addresultfilenames/src/main/java/org/apache/hop/workflow/actions/addresultfilenames/ActionAddResultFilenames.java
@@ -84,19 +84,6 @@ public class ActionAddResultFilenames extends ActionBase implements Cloneable, I
     this("");
   }
 
-  public ActionAddResultFilenames(ActionAddResultFilenames other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.argFromPrevious = other.argFromPrevious;
-    this.arguments = other.arguments;
-    this.deleteAllBefore = other.deleteAllBefore;
-    this.includeSubFolders = other.includeSubFolders;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionAddResultFilenames(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     List<RowMetaAndData> rows = result.getRows();
diff --git a/plugins/actions/checkfilelocked/src/main/java/org/apache/hop/workflow/actions/checkfilelocked/ActionCheckFilesLocked.java b/plugins/actions/checkfilelocked/src/main/java/org/apache/hop/workflow/actions/checkfilelocked/ActionCheckFilesLocked.java
index e4ed8838e9..a473b4b10d 100644
--- a/plugins/actions/checkfilelocked/src/main/java/org/apache/hop/workflow/actions/checkfilelocked/ActionCheckFilesLocked.java
+++ b/plugins/actions/checkfilelocked/src/main/java/org/apache/hop/workflow/actions/checkfilelocked/ActionCheckFilesLocked.java
@@ -70,11 +70,6 @@ public class ActionCheckFilesLocked extends ActionBase implements Cloneable, IAc
     this("");
   }
 
-  @Override
-  public ActionCheckFilesLocked clone() {
-    return new ActionCheckFilesLocked(this);
-  }
-
   public ActionCheckFilesLocked(ActionCheckFilesLocked other) {
     super(other.getName(), other.getDescription(), other.getPluginId());
     this.checkedFiles = new ArrayList<>();
diff --git a/plugins/actions/columnsexist/src/main/java/org/apache/hop/workflow/actions/columnsexist/ActionColumnsExist.java b/plugins/actions/columnsexist/src/main/java/org/apache/hop/workflow/actions/columnsexist/ActionColumnsExist.java
index 3b3ce60893..1b032bdc78 100644
--- a/plugins/actions/columnsexist/src/main/java/org/apache/hop/workflow/actions/columnsexist/ActionColumnsExist.java
+++ b/plugins/actions/columnsexist/src/main/java/org/apache/hop/workflow/actions/columnsexist/ActionColumnsExist.java
@@ -101,19 +101,6 @@ public class ActionColumnsExist extends ActionBase implements Cloneable, IAction
     this("");
   }
 
-  public ActionColumnsExist(ActionColumnsExist meta) {
-    super(meta.getName(), meta.getDescription(), meta.getPluginId());
-    this.schemaName = meta.schemaName;
-    this.tableName = meta.tableName;
-    this.connectionName = meta.connectionName;
-    this.columns = meta.columns;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionColumnsExist(this);
-  }
-
   @Override
   public boolean isEvaluation() {
     return true;
diff --git a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFiles.java b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFiles.java
index 76fe072d69..94926142dc 100644
--- a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFiles.java
+++ b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFiles.java
@@ -144,39 +144,13 @@ public class ActionCopyFiles extends ActionBase implements ILegacyXml {
     this("");
   }
 
-  public ActionCopyFiles(ActionCopyFiles other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.copyEmptyFolders = other.copyEmptyFolders;
-    this.argFromPrevious = other.argFromPrevious;
-    this.overwriteFiles = other.overwriteFiles;
-    this.includeSubFolders = other.includeSubFolders;
-    this.removeSourceFiles = other.removeSourceFiles;
-    this.addResultFilenames = other.addResultFilenames;
-    this.destinationIsAFile = other.destinationIsAFile;
-    this.createDestinationFolder = other.createDestinationFolder;
-    this.fileRows = new ArrayList<>();
-    if (other.fileRows != null) {
-      for (CopyFilesItem row : other.fileRows) {
-        this.fileRows.add(
-            new CopyFilesItem(
-                row.getSourceFileFolder(), row.getDestinationFileFolder(), row.getWildcard()));
-      }
-    }
-  }
-
   @Override
   public Object clone() {
     ActionCopyFiles copy = (ActionCopyFiles) super.clone();
+    // Bookkeeping for a single execution, not part of the action's configuration, so it is not
+    // carried over to the copy.
     copy.listFilesRemove = new HashSet<>();
     copy.listAddResult = new HashSet<>();
-    copy.fileRows = new ArrayList<>();
-    if (fileRows != null) {
-      for (CopyFilesItem row : fileRows) {
-        copy.fileRows.add(
-            new CopyFilesItem(
-                row.getSourceFileFolder(), row.getDestinationFileFolder(), row.getWildcard()));
-      }
-    }
     return copy;
   }
 
diff --git a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
index 4db726d90f..0200572e8e 100644
--- a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
+++ b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
@@ -163,39 +163,6 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
     this("");
   }
 
-  public ActionCopyMoveResultFilenames(ActionCopyMoveResultFilenames a) {
-    super(a);
-    this.folderName = a.folderName;
-    this.specifyWildcard = a.specifyWildcard;
-    this.wildcard = a.wildcard;
-    this.wildcardExclude = a.wildcardExclude;
-    this.destinationFolder = a.destinationFolder;
-    this.nrErrorsLessThan = a.nrErrorsLessThan;
-    this.successCondition = a.successCondition;
-    this.addDate = a.addDate;
-    this.addTime = a.addTime;
-    this.specifyFormat = a.specifyFormat;
-    this.dateTimeFormat = a.dateTimeFormat;
-    this.addDateBeforeExtension = a.addDateBeforeExtension;
-    this.action = a.action;
-    this.overwriteFile = a.overwriteFile;
-    this.createDestinationFolder = a.createDestinationFolder;
-    this.removedSourceFilename = a.removedSourceFilename;
-    this.addDestinationFilename = a.addDestinationFilename;
-
-    this.nrErrors = 0;
-    this.nrSuccess = 0;
-    this.successConditionBroken = false;
-    this.limitFiles = 0;
-    this.wildcardPattern = null;
-    this.wildcardExcludePattern = null;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionCopyMoveResultFilenames(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) {
     result.setNrErrors(1);
diff --git a/plugins/actions/createfolder/src/main/java/org/apache/hop/workflow/actions/createfolder/ActionCreateFolder.java b/plugins/actions/createfolder/src/main/java/org/apache/hop/workflow/actions/createfolder/ActionCreateFolder.java
index 2c1b258816..8d78d71b59 100644
--- a/plugins/actions/createfolder/src/main/java/org/apache/hop/workflow/actions/createfolder/ActionCreateFolder.java
+++ b/plugins/actions/createfolder/src/main/java/org/apache/hop/workflow/actions/createfolder/ActionCreateFolder.java
@@ -67,17 +67,6 @@ public class ActionCreateFolder extends ActionBase implements Cloneable, IAction
     this("");
   }
 
-  public ActionCreateFolder(ActionCreateFolder f) {
-    super(f.getName(), f.getDescription(), f.getPluginId());
-    this.folderName = f.folderName;
-    this.failIfFolderExists = f.failIfFolderExists;
-  }
-
-  @Override
-  public ActionCreateFolder clone() {
-    return new ActionCreateFolder(this);
-  }
-
   @Override
   public Result execute(Result previousResult, int nr) {
     Result result = previousResult;
diff --git a/plugins/actions/dbt/src/main/java/org/apache/hop/workflow/actions/dbt/ActionDbt.java b/plugins/actions/dbt/src/main/java/org/apache/hop/workflow/actions/dbt/ActionDbt.java
index 612330aa58..5629117dbb 100644
--- a/plugins/actions/dbt/src/main/java/org/apache/hop/workflow/actions/dbt/ActionDbt.java
+++ b/plugins/actions/dbt/src/main/java/org/apache/hop/workflow/actions/dbt/ActionDbt.java
@@ -127,16 +127,6 @@ public class ActionDbt extends ActionBase implements IAction {
     this.envVars = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    ActionDbt copy = (ActionDbt) super.clone();
-    // super.clone() is shallow: without this, a copied action shares its var lists with the
-    // original and editing one edits both.
-    copy.vars = copyPairs(vars);
-    copy.envVars = copyPairs(envVars);
-    return copy;
-  }
-
   private static List<DbtNameValue> copyPairs(List<DbtNameValue> source) {
     List<DbtNameValue> copy = new ArrayList<>();
     if (source != null) {
diff --git a/plugins/actions/delay/src/main/java/org/apache/hop/workflow/actions/delay/ActionDelay.java b/plugins/actions/delay/src/main/java/org/apache/hop/workflow/actions/delay/ActionDelay.java
index 41cb0e1d8a..5ba66b60c2 100644
--- a/plugins/actions/delay/src/main/java/org/apache/hop/workflow/actions/delay/ActionDelay.java
+++ b/plugins/actions/delay/src/main/java/org/apache/hop/workflow/actions/delay/ActionDelay.java
@@ -60,17 +60,6 @@ public class ActionDelay extends ActionBase implements Cloneable {
     this("");
   }
 
-  public ActionDelay(ActionDelay other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.maximumTimeout = other.maximumTimeout;
-    this.scaleTime = other.scaleTime;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionDelay(this);
-  }
-
   /**
    * Execute this action and return the result. In this case it means, just set the result boolean
    * in the Result class.
diff --git a/plugins/actions/deletefile/src/main/java/org/apache/hop/workflow/actions/deletefile/ActionDeleteFile.java b/plugins/actions/deletefile/src/main/java/org/apache/hop/workflow/actions/deletefile/ActionDeleteFile.java
index cb67731952..f78125bb06 100644
--- a/plugins/actions/deletefile/src/main/java/org/apache/hop/workflow/actions/deletefile/ActionDeleteFile.java
+++ b/plugins/actions/deletefile/src/main/java/org/apache/hop/workflow/actions/deletefile/ActionDeleteFile.java
@@ -72,17 +72,6 @@ public class ActionDeleteFile extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  public ActionDeleteFile(ActionDeleteFile meta) {
-    super(meta.getName(), meta.getDescription(), meta.getPluginId());
-    this.filename = meta.filename;
-    this.failIfFileNotExists = meta.failIfFileNotExists;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionDeleteFile(this);
-  }
-
   public void setFilename(String filename) {
     this.filename = filename;
   }
diff --git a/plugins/actions/deletefiles/src/main/java/org/apache/hop/workflow/actions/deletefiles/ActionDeleteFiles.java b/plugins/actions/deletefiles/src/main/java/org/apache/hop/workflow/actions/deletefiles/ActionDeleteFiles.java
index 9eb383c2ee..eed75729f5 100644
--- a/plugins/actions/deletefiles/src/main/java/org/apache/hop/workflow/actions/deletefiles/ActionDeleteFiles.java
+++ b/plugins/actions/deletefiles/src/main/java/org/apache/hop/workflow/actions/deletefiles/ActionDeleteFiles.java
@@ -19,7 +19,6 @@ package org.apache.hop.workflow.actions.deletefiles;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
@@ -88,18 +87,6 @@ public class ActionDeleteFiles extends ActionBase {
     this("");
   }
 
-  public ActionDeleteFiles(ActionDeleteFiles other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.argFromPrevious = other.argFromPrevious;
-    this.includeSubfolders = other.includeSubfolders;
-    this.fileItems = new ArrayList<>(other.fileItems);
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionDeleteFiles(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     List<RowMetaAndData> resultRows = result.getRows();
diff --git a/plugins/actions/deletefolders/src/main/java/org/apache/hop/workflow/actions/deletefolders/ActionDeleteFolders.java b/plugins/actions/deletefolders/src/main/java/org/apache/hop/workflow/actions/deletefolders/ActionDeleteFolders.java
index c0cd1fee59..4f23b7682a 100644
--- a/plugins/actions/deletefolders/src/main/java/org/apache/hop/workflow/actions/deletefolders/ActionDeleteFolders.java
+++ b/plugins/actions/deletefolders/src/main/java/org/apache/hop/workflow/actions/deletefolders/ActionDeleteFolders.java
@@ -17,7 +17,6 @@
 
 package org.apache.hop.workflow.actions.deletefolders;
 
-import java.util.ArrayList;
 import java.util.List;
 import lombok.Getter;
 import lombok.Setter;
@@ -125,19 +124,6 @@ public class ActionDeleteFolders extends ActionBase {
     limitFolders = "10";
   }
 
-  public ActionDeleteFolders(ActionDeleteFolders other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.argFromPrevious = other.argFromPrevious;
-    this.limitFolders = other.limitFolders;
-    this.successCondition = other.successCondition;
-    this.fileItems = new ArrayList<>(other.fileItems);
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionDeleteFolders(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     List<RowMetaAndData> rows = result.getRows();
diff --git a/plugins/actions/deleteresultfilenames/src/main/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenames.java b/plugins/actions/deleteresultfilenames/src/main/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenames.java
index c01dddcfc7..c9a470880a 100644
--- a/plugins/actions/deleteresultfilenames/src/main/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenames.java
+++ b/plugins/actions/deleteresultfilenames/src/main/java/org/apache/hop/workflow/actions/deleteresultfilenames/ActionDeleteResultFilenames.java
@@ -78,18 +78,6 @@ public class ActionDeleteResultFilenames extends ActionBase implements Cloneable
     this("");
   }
 
-  public ActionDeleteResultFilenames(ActionDeleteResultFilenames a) {
-    super(a);
-    this.specifyWildcard = a.specifyWildcard;
-    this.wildcard = a.wildcard;
-    this.wildcardExclude = a.wildcardExclude;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionDeleteResultFilenames(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) {
     result.setResult(false);
diff --git a/plugins/actions/eval/src/main/java/org/apache/hop/workflow/actions/eval/ActionEval.java b/plugins/actions/eval/src/main/java/org/apache/hop/workflow/actions/eval/ActionEval.java
index 084e216af2..d923bd8fc0 100644
--- a/plugins/actions/eval/src/main/java/org/apache/hop/workflow/actions/eval/ActionEval.java
+++ b/plugins/actions/eval/src/main/java/org/apache/hop/workflow/actions/eval/ActionEval.java
@@ -63,16 +63,6 @@ public class ActionEval extends ActionBase implements Cloneable, IAction {
     this("", "");
   }
 
-  public ActionEval(ActionEval other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.script = other.script;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionEval(this);
-  }
-
   public void setScript(String s) {
     script = s;
   }
diff --git a/plugins/actions/evalfilesmetrics/src/main/java/org/apache/hop/workflow/actions/evalfilesmetrics/ActionEvalFilesMetrics.java b/plugins/actions/evalfilesmetrics/src/main/java/org/apache/hop/workflow/actions/evalfilesmetrics/ActionEvalFilesMetrics.java
index 4e645b85bf..de34c40b42 100644
--- a/plugins/actions/evalfilesmetrics/src/main/java/org/apache/hop/workflow/actions/evalfilesmetrics/ActionEvalFilesMetrics.java
+++ b/plugins/actions/evalfilesmetrics/src/main/java/org/apache/hop/workflow/actions/evalfilesmetrics/ActionEvalFilesMetrics.java
@@ -140,34 +140,6 @@ public class ActionEvalFilesMetrics extends ActionBase implements Cloneable, IAc
     sourceFiles = new ArrayList<>();
   }
 
-  public ActionEvalFilesMetrics(ActionEvalFilesMetrics a) {
-    super(a);
-    this.scale = a.scale;
-    this.sourceFilesType = a.sourceFilesType;
-    this.evaluationType = a.evaluationType;
-    this.compareValue = a.compareValue;
-    this.minValue = a.minValue;
-    this.maxValue = a.maxValue;
-    this.successConditionType = a.successConditionType;
-    this.resultFilenamesWildcard = a.resultFilenamesWildcard;
-    this.resultFieldFile = a.resultFieldFile;
-    this.resultFieldWildcard = a.resultFieldWildcard;
-    this.resultFieldIncludeSubFolders = a.resultFieldIncludeSubFolders;
-    this.realCompareValue = a.realCompareValue;
-    this.realMinValue = a.realMinValue;
-    this.realMaxValue = a.realMaxValue;
-    this.realEvaluationValue = a.realEvaluationValue;
-    this.realFilesCount = a.realFilesCount;
-    this.nrErrors = a.nrErrors;
-    this.sourceFiles = new ArrayList<>();
-    a.sourceFiles.forEach(f -> this.sourceFiles.add(new SourceFile(f)));
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionEvalFilesMetrics(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     result.setNrErrors(1);
diff --git a/plugins/actions/filecompare/src/main/java/org/apache/hop/workflow/actions/filecompare/ActionFileCompare.java b/plugins/actions/filecompare/src/main/java/org/apache/hop/workflow/actions/filecompare/ActionFileCompare.java
index 6b0e7c9a7a..e38dc6ba19 100644
--- a/plugins/actions/filecompare/src/main/java/org/apache/hop/workflow/actions/filecompare/ActionFileCompare.java
+++ b/plugins/actions/filecompare/src/main/java/org/apache/hop/workflow/actions/filecompare/ActionFileCompare.java
@@ -80,18 +80,6 @@ public class ActionFileCompare extends ActionBase implements Cloneable, IAction
     this("");
   }
 
-  public ActionFileCompare(ActionFileCompare meta) {
-    super(meta.getName(), meta.getDescription(), meta.getPluginId());
-    this.filename1 = meta.filename1;
-    this.filename2 = meta.filename2;
-    this.addFilenameToResult = meta.addFilenameToResult;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionFileCompare(this);
-  }
-
   public String getRealFilename1() {
     return resolve(getFilename1());
   }
diff --git a/plugins/actions/fileexists/src/main/java/org/apache/hop/workflow/actions/fileexists/ActionFileExists.java b/plugins/actions/fileexists/src/main/java/org/apache/hop/workflow/actions/fileexists/ActionFileExists.java
index c32da35462..df6da8281b 100644
--- a/plugins/actions/fileexists/src/main/java/org/apache/hop/workflow/actions/fileexists/ActionFileExists.java
+++ b/plugins/actions/fileexists/src/main/java/org/apache/hop/workflow/actions/fileexists/ActionFileExists.java
@@ -68,16 +68,6 @@ public class ActionFileExists extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  public ActionFileExists(ActionFileExists meta) {
-    super(meta.getName(), meta.getDescription(), meta.getPluginId());
-    this.filename = meta.filename;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionFileExists(this);
-  }
-
   public void setFilename(String filename) {
     this.filename = filename;
   }
diff --git a/plugins/actions/filesexist/src/main/java/org/apache/hop/workflow/actions/filesexist/ActionFilesExist.java b/plugins/actions/filesexist/src/main/java/org/apache/hop/workflow/actions/filesexist/ActionFilesExist.java
index b92ebaa060..9a58fcf8e0 100644
--- a/plugins/actions/filesexist/src/main/java/org/apache/hop/workflow/actions/filesexist/ActionFilesExist.java
+++ b/plugins/actions/filesexist/src/main/java/org/apache/hop/workflow/actions/filesexist/ActionFilesExist.java
@@ -17,7 +17,6 @@
 
 package org.apache.hop.workflow.actions.filesexist;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
 import lombok.Getter;
@@ -67,16 +66,6 @@ public class ActionFilesExist extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  public ActionFilesExist(ActionFilesExist other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.fileItems = new ArrayList<>(other.fileItems);
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionFilesExist(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) {
     result.setResult(false);
diff --git a/plugins/actions/folderisempty/src/main/java/org/apache/hop/workflow/actions/folderisempty/ActionFolderIsEmpty.java b/plugins/actions/folderisempty/src/main/java/org/apache/hop/workflow/actions/folderisempty/ActionFolderIsEmpty.java
index f01f4a5de2..0473ec33cb 100644
--- a/plugins/actions/folderisempty/src/main/java/org/apache/hop/workflow/actions/folderisempty/ActionFolderIsEmpty.java
+++ b/plugins/actions/folderisempty/src/main/java/org/apache/hop/workflow/actions/folderisempty/ActionFolderIsEmpty.java
@@ -84,19 +84,6 @@ public class ActionFolderIsEmpty extends ActionBase implements Cloneable, IActio
     this("");
   }
 
-  public ActionFolderIsEmpty(ActionFolderIsEmpty meta) {
-    super(meta.getName(), meta.getDescription(), meta.getPluginId());
-    this.folderName = meta.folderName;
-    this.includeSubFolders = meta.includeSubFolders;
-    this.specifyWildcard = meta.specifyWildcard;
-    this.wildcard = meta.wildcard;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionFolderIsEmpty(this);
-  }
-
   public void setSpecifyWildcard(boolean specifyWildcard) {
     this.specifyWildcard = specifyWildcard;
   }
diff --git a/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompare.java b/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompare.java
index 356ef35a25..374e40314c 100644
--- a/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompare.java
+++ b/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompare.java
@@ -110,22 +110,6 @@ public class ActionFoldersCompare extends ActionBase implements Cloneable, IActi
     this("");
   }
 
-  public ActionFoldersCompare(ActionFoldersCompare a) {
-    super(a);
-    this.includeSubFolders = a.includeSubFolders;
-    this.compareFileContent = a.compareFileContent;
-    this.compareFileSize = a.compareFileSize;
-    this.compareOnly = a.compareOnly;
-    this.wildcard = a.wildcard;
-    this.filename1 = a.filename1;
-    this.filename2 = a.filename2;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionFoldersCompare(this);
-  }
-
   public String getRealWildcard() {
     return resolve(getWildcard());
   }
diff --git a/plugins/actions/join/src/main/java/org/apache/hop/workflow/actions/join/ActionJoin.java b/plugins/actions/join/src/main/java/org/apache/hop/workflow/actions/join/ActionJoin.java
index ee713c9bb5..45cbe83cb3 100644
--- a/plugins/actions/join/src/main/java/org/apache/hop/workflow/actions/join/ActionJoin.java
+++ b/plugins/actions/join/src/main/java/org/apache/hop/workflow/actions/join/ActionJoin.java
@@ -56,11 +56,6 @@ public class ActionJoin extends ActionBase {
     super(other.getName(), other.getDescription(), other.getPluginId());
   }
 
-  @Override
-  public Object clone() {
-    return new ActionJoin(this);
-  }
-
   /**
    * Execute this action and return the result. In this case it means, just set the result boolean
    * in the Result class.
diff --git a/plugins/actions/movefiles/src/main/java/org/apache/hop/workflow/actions/movefiles/ActionMoveFiles.java b/plugins/actions/movefiles/src/main/java/org/apache/hop/workflow/actions/movefiles/ActionMoveFiles.java
index 831f4df335..7eff6b0be7 100644
--- a/plugins/actions/movefiles/src/main/java/org/apache/hop/workflow/actions/movefiles/ActionMoveFiles.java
+++ b/plugins/actions/movefiles/src/main/java/org/apache/hop/workflow/actions/movefiles/ActionMoveFiles.java
@@ -181,47 +181,6 @@ public class ActionMoveFiles extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  public ActionMoveFiles(ActionMoveFiles a) {
-    super(a);
-    this.moveEmptyFolders = a.moveEmptyFolders;
-    this.argFromPrevious = a.argFromPrevious;
-    this.includeSubfolders = a.includeSubfolders;
-    this.addResultFilenames = a.addResultFilenames;
-    this.destinationIsAFile = a.destinationIsAFile;
-    this.createDestinationFolder = a.createDestinationFolder;
-    this.nrErrorsLessThan = a.nrErrorsLessThan;
-    this.successCondition = a.successCondition;
-    this.addDate = a.addDate;
-    this.addTime = a.addTime;
-    this.specifyFormat = a.specifyFormat;
-    this.dateTimeFormat = a.dateTimeFormat;
-    this.addDateBeforeExtension = a.addDateBeforeExtension;
-    this.doNotKeepFolderStructure = a.doNotKeepFolderStructure;
-    this.ifFileExists = a.ifFileExists;
-    this.destinationFolder = a.destinationFolder;
-    this.ifMovedFileExists = a.ifMovedFileExists;
-    this.movedDateTimeFormat = a.movedDateTimeFormat;
-    this.addMovedDateBeforeExtension = a.addMovedDateBeforeExtension;
-    this.addMovedDate = a.addMovedDate;
-    this.addMovedTime = a.addMovedTime;
-    this.specifyMoveFormat = a.specifyMoveFormat;
-    this.createMoveToFolder = a.createMoveToFolder;
-    this.simulate = a.simulate;
-    this.filesToMove = new ArrayList<>();
-    a.filesToMove.forEach(f -> filesToMove.add(new FileToMove(f)));
-
-    this.nrErrors = 0;
-    this.nrSuccess = 0;
-    this.successConditionBroken = false;
-    this.successConditionBrokenExit = false;
-    this.limitFiles = 0;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionMoveFiles(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     List<RowMetaAndData> rows = result.getRows();
diff --git a/plugins/actions/pgpfiles/src/main/java/org/apache/hop/workflow/actions/pgpdecryptfiles/ActionPGPDecryptFiles.java b/plugins/actions/pgpfiles/src/main/java/org/apache/hop/workflow/actions/pgpdecryptfiles/ActionPGPDecryptFiles.java
index de6254ca78..82c0407b14 100644
--- a/plugins/actions/pgpfiles/src/main/java/org/apache/hop/workflow/actions/pgpdecryptfiles/ActionPGPDecryptFiles.java
+++ b/plugins/actions/pgpfiles/src/main/java/org/apache/hop/workflow/actions/pgpdecryptfiles/ActionPGPDecryptFiles.java
@@ -180,48 +180,6 @@ public class ActionPGPDecryptFiles extends ActionBase implements Cloneable, IAct
     this("");
   }
 
-  public ActionPGPDecryptFiles(ActionPGPDecryptFiles a) {
-    super(a);
-    this.argFromPrevious = a.argFromPrevious;
-    this.includeSubFolders = a.includeSubFolders;
-    this.addResultFilenames = a.addResultFilenames;
-    this.destinationIsAFile = a.destinationIsAFile;
-    this.createDestinationFolder = a.createDestinationFolder;
-    this.nrErrorsLessThan = a.nrErrorsLessThan;
-    this.successCondition = a.successCondition;
-    this.addDate = a.addDate;
-    this.addTime = a.addTime;
-    this.specifyFormat = a.specifyFormat;
-    this.dateTimeFormat = a.dateTimeFormat;
-    this.addDateBeforeExtension = a.addDateBeforeExtension;
-    this.doNotKeepFolderStructure = a.doNotKeepFolderStructure;
-    this.ifFileExists = a.ifFileExists;
-    this.destinationFolder = a.destinationFolder;
-    this.ifMovedFileExists = a.ifMovedFileExists;
-    this.movedDateTimeFormat = a.movedDateTimeFormat;
-    this.addMovedDateBeforeExtension = a.addMovedDateBeforeExtension;
-    this.addMovedDate = a.addMovedDate;
-    this.addMovedTime = a.addMovedTime;
-    this.specifyMoveFormat = a.specifyMoveFormat;
-    this.createMoveToFolder = a.createMoveToFolder;
-    this.gpgLocation = a.gpgLocation;
-    this.filesToDecrypt = new ArrayList<>();
-    a.filesToDecrypt.forEach(f -> filesToDecrypt.add(new FileToDecrypt(f)));
-
-    this.daf = null;
-    this.gpg = null;
-    this.nrErrors = 0;
-    this.nrSuccess = 0;
-    this.successConditionBroken = false;
-    this.successConditionBrokenExit = false;
-    this.limitFiles = 0;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionPGPDecryptFiles(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     List<RowMetaAndData> rows = result.getRows();
diff --git a/plugins/actions/pgpfiles/src/main/java/org/apache/hop/workflow/actions/pgpverify/ActionPGPVerify.java b/plugins/actions/pgpfiles/src/main/java/org/apache/hop/workflow/actions/pgpverify/ActionPGPVerify.java
index 18a85ff757..a9a90a24cc 100644
--- a/plugins/actions/pgpfiles/src/main/java/org/apache/hop/workflow/actions/pgpverify/ActionPGPVerify.java
+++ b/plugins/actions/pgpfiles/src/main/java/org/apache/hop/workflow/actions/pgpverify/ActionPGPVerify.java
@@ -83,19 +83,6 @@ public class ActionPGPVerify extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  public ActionPGPVerify(ActionPGPVerify a) {
-    super(a);
-    this.gpgLocation = a.gpgLocation;
-    this.filename = a.filename;
-    this.detachedFilename = a.detachedFilename;
-    this.useDetachedSignature = a.useDetachedSignature;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionPGPVerify(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) {
     result.setResult(false);
diff --git a/plugins/actions/ping/src/main/java/org/apache/hop/workflow/actions/ping/ActionPing.java b/plugins/actions/ping/src/main/java/org/apache/hop/workflow/actions/ping/ActionPing.java
index c156ae3bf4..7c9900a0fe 100644
--- a/plugins/actions/ping/src/main/java/org/apache/hop/workflow/actions/ping/ActionPing.java
+++ b/plugins/actions/ping/src/main/java/org/apache/hop/workflow/actions/ping/ActionPing.java
@@ -101,12 +101,6 @@ public class ActionPing extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionPing je = (ActionPing) super.clone();
-    return je;
-  }
-
   public String getRealNbrPackets() {
     return resolve(getNbrPackets());
   }
diff --git a/plugins/actions/repeat/src/main/java/org/apache/hop/workflow/actions/repeat/EndRepeat.java b/plugins/actions/repeat/src/main/java/org/apache/hop/workflow/actions/repeat/EndRepeat.java
index 845210c854..5c9d0ac3bf 100644
--- a/plugins/actions/repeat/src/main/java/org/apache/hop/workflow/actions/repeat/EndRepeat.java
+++ b/plugins/actions/repeat/src/main/java/org/apache/hop/workflow/actions/repeat/EndRepeat.java
@@ -62,11 +62,6 @@ public class EndRepeat extends ActionBase implements IAction, Cloneable {
     return prevResult;
   }
 
-  @Override
-  public EndRepeat clone() {
-    return (EndRepeat) super.clone();
-  }
-
   @Override
   public boolean isEvaluation() {
     return true;
diff --git a/plugins/actions/repeat/src/main/java/org/apache/hop/workflow/actions/repeat/Repeat.java b/plugins/actions/repeat/src/main/java/org/apache/hop/workflow/actions/repeat/Repeat.java
index a89c76e2fb..02aff31a53 100644
--- a/plugins/actions/repeat/src/main/java/org/apache/hop/workflow/actions/repeat/Repeat.java
+++ b/plugins/actions/repeat/src/main/java/org/apache/hop/workflow/actions/repeat/Repeat.java
@@ -145,11 +145,6 @@ public class Repeat extends ActionBase implements IAction, Cloneable {
     this("", "");
   }
 
-  @Override
-  public Repeat clone() {
-    return (Repeat) super.clone();
-  }
-
   @Override
   public Result execute(Result prevResult, int nr) throws HopException {
 
diff --git a/plugins/actions/sendnagiospassivecheck/src/main/java/org/apache/hop/workflow/actions/sendnagiospassivecheck/ActionSendNagiosPassiveCheck.java b/plugins/actions/sendnagiospassivecheck/src/main/java/org/apache/hop/workflow/actions/sendnagiospassivecheck/ActionSendNagiosPassiveCheck.java
index 3bdb98da74..4d3f423b27 100644
--- a/plugins/actions/sendnagiospassivecheck/src/main/java/org/apache/hop/workflow/actions/sendnagiospassivecheck/ActionSendNagiosPassiveCheck.java
+++ b/plugins/actions/sendnagiospassivecheck/src/main/java/org/apache/hop/workflow/actions/sendnagiospassivecheck/ActionSendNagiosPassiveCheck.java
@@ -138,12 +138,6 @@ public class ActionSendNagiosPassiveCheck extends ActionBase implements Cloneabl
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionSendNagiosPassiveCheck je = (ActionSendNagiosPassiveCheck) super.clone();
-    return je;
-  }
-
   public static String getEncryptionModeDesc(int i) {
     if (i < 0 || i >= encryptionModeDesc.length) {
       return encryptionModeDesc[0];
diff --git a/plugins/actions/setpasswordencoder/src/main/java/org/apache/hop/workflow/actions/setpasswordencoder/ActionSetPasswordEncoder.java b/plugins/actions/setpasswordencoder/src/main/java/org/apache/hop/workflow/actions/setpasswordencoder/ActionSetPasswordEncoder.java
index 4fc185f293..4b5716b66e 100644
--- a/plugins/actions/setpasswordencoder/src/main/java/org/apache/hop/workflow/actions/setpasswordencoder/ActionSetPasswordEncoder.java
+++ b/plugins/actions/setpasswordencoder/src/main/java/org/apache/hop/workflow/actions/setpasswordencoder/ActionSetPasswordEncoder.java
@@ -79,18 +79,6 @@ public class ActionSetPasswordEncoder extends ActionBase implements Cloneable, I
     this("");
   }
 
-  public ActionSetPasswordEncoder(ActionSetPasswordEncoder other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.encoderPluginId = other.encoderPluginId;
-    this.keyVariable = other.keyVariable;
-    this.keyFile = other.keyFile;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionSetPasswordEncoder(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     result.setResult(false);
diff --git a/plugins/actions/setvariables/src/main/java/org/apache/hop/workflow/actions/setvariables/ActionSetVariables.java b/plugins/actions/setvariables/src/main/java/org/apache/hop/workflow/actions/setvariables/ActionSetVariables.java
index 7f375f23ec..fc12db0242 100644
--- a/plugins/actions/setvariables/src/main/java/org/apache/hop/workflow/actions/setvariables/ActionSetVariables.java
+++ b/plugins/actions/setvariables/src/main/java/org/apache/hop/workflow/actions/setvariables/ActionSetVariables.java
@@ -167,19 +167,6 @@ public class ActionSetVariables extends ActionBase implements Cloneable, IAction
     this("");
   }
 
-  public ActionSetVariables(ActionSetVariables other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.filename = other.getFilename();
-    this.fileVariableType = other.getFileVariableType();
-    this.replaceVars = other.isReplaceVars();
-    this.variableDefinitions = other.getVariableDefinitions();
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionSetVariables(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     result.setResult(true);
diff --git a/plugins/actions/simpleeval/src/main/java/org/apache/hop/workflow/actions/simpleeval/ActionSimpleEval.java b/plugins/actions/simpleeval/src/main/java/org/apache/hop/workflow/actions/simpleeval/ActionSimpleEval.java
index e25ba90a06..c6746d360c 100644
--- a/plugins/actions/simpleeval/src/main/java/org/apache/hop/workflow/actions/simpleeval/ActionSimpleEval.java
+++ b/plugins/actions/simpleeval/src/main/java/org/apache/hop/workflow/actions/simpleeval/ActionSimpleEval.java
@@ -332,12 +332,6 @@ public class ActionSimpleEval extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionSimpleEval je = (ActionSimpleEval) super.clone();
-    return je;
-  }
-
   public void setSuccessWhenVarSet(boolean successwhenvarset) {
     this.successWhenVarSet = successwhenvarset;
   }
diff --git a/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSql.java b/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSql.java
index 814762671f..dec3fd538e 100644
--- a/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSql.java
+++ b/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSql.java
@@ -101,12 +101,6 @@ public class ActionSql extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionSql je = (ActionSql) super.clone();
-    return je;
-  }
-
   @Override
   public Result execute(Result previousResult, int nr) {
     Result result = previousResult;
diff --git a/plugins/actions/success/src/main/java/org/apache/hop/workflow/actions/success/ActionSuccess.java b/plugins/actions/success/src/main/java/org/apache/hop/workflow/actions/success/ActionSuccess.java
index 42c7ee427a..22f7f13ed2 100644
--- a/plugins/actions/success/src/main/java/org/apache/hop/workflow/actions/success/ActionSuccess.java
+++ b/plugins/actions/success/src/main/java/org/apache/hop/workflow/actions/success/ActionSuccess.java
@@ -47,12 +47,6 @@ public class ActionSuccess extends ActionBase implements Cloneable, IAction {
     this("", "");
   }
 
-  @Override
-  public Object clone() {
-    ActionSuccess je = (ActionSuccess) super.clone();
-    return je;
-  }
-
   /**
    * Execute this action and return the result. In this case it means, just set the result boolean
    * in the Result class.
diff --git a/plugins/actions/tableexists/src/main/java/org/apache/hop/workflow/actions/tableexists/ActionTableExists.java b/plugins/actions/tableexists/src/main/java/org/apache/hop/workflow/actions/tableexists/ActionTableExists.java
index 61faf72104..2bd8e966c1 100644
--- a/plugins/actions/tableexists/src/main/java/org/apache/hop/workflow/actions/tableexists/ActionTableExists.java
+++ b/plugins/actions/tableexists/src/main/java/org/apache/hop/workflow/actions/tableexists/ActionTableExists.java
@@ -77,12 +77,6 @@ public class ActionTableExists extends ActionBase implements Cloneable, IAction
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionTableExists je = (ActionTableExists) super.clone();
-    return je;
-  }
-
   public void setTableName(String tableName) {
     this.tableName = tableName;
   }
diff --git a/plugins/actions/telnet/src/main/java/org/apache/hop/workflow/actions/telnet/ActionTelnet.java b/plugins/actions/telnet/src/main/java/org/apache/hop/workflow/actions/telnet/ActionTelnet.java
index cba777c278..d4a349138b 100644
--- a/plugins/actions/telnet/src/main/java/org/apache/hop/workflow/actions/telnet/ActionTelnet.java
+++ b/plugins/actions/telnet/src/main/java/org/apache/hop/workflow/actions/telnet/ActionTelnet.java
@@ -72,12 +72,6 @@ public class ActionTelnet extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionTelnet je = (ActionTelnet) super.clone();
-    return je;
-  }
-
   public String getPort() {
     return port;
   }
diff --git a/plugins/actions/unzip/src/main/java/org/apache/hop/workflow/actions/unzip/ActionUnZip.java b/plugins/actions/unzip/src/main/java/org/apache/hop/workflow/actions/unzip/ActionUnZip.java
index 981b89afb2..89088fb93e 100644
--- a/plugins/actions/unzip/src/main/java/org/apache/hop/workflow/actions/unzip/ActionUnZip.java
+++ b/plugins/actions/unzip/src/main/java/org/apache/hop/workflow/actions/unzip/ActionUnZip.java
@@ -193,12 +193,6 @@ public class ActionUnZip extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionUnZip je = (ActionUnZip) super.clone();
-    return je;
-  }
-
   @Override
   public Result execute(Result previousResult, int nr) {
     Result result = previousResult;
diff --git a/plugins/actions/waitforfile/src/main/java/org/apache/hop/workflow/actions/waitforfile/ActionWaitForFile.java b/plugins/actions/waitforfile/src/main/java/org/apache/hop/workflow/actions/waitforfile/ActionWaitForFile.java
index 7d57fa9a94..74bbdba77e 100644
--- a/plugins/actions/waitforfile/src/main/java/org/apache/hop/workflow/actions/waitforfile/ActionWaitForFile.java
+++ b/plugins/actions/waitforfile/src/main/java/org/apache/hop/workflow/actions/waitforfile/ActionWaitForFile.java
@@ -93,12 +93,6 @@ public class ActionWaitForFile extends ActionBase implements Cloneable, IAction
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionWaitForFile je = (ActionWaitForFile) super.clone();
-    return je;
-  }
-
   public void setFilename(String filename) {
     this.filename = filename;
   }
diff --git a/plugins/actions/waitforsql/src/main/java/org/apache/hop/workflow/actions/waitforsql/ActionWaitForSql.java b/plugins/actions/waitforsql/src/main/java/org/apache/hop/workflow/actions/waitforsql/ActionWaitForSql.java
index 486f2b499c..e24a42a67a 100644
--- a/plugins/actions/waitforsql/src/main/java/org/apache/hop/workflow/actions/waitforsql/ActionWaitForSql.java
+++ b/plugins/actions/waitforsql/src/main/java/org/apache/hop/workflow/actions/waitforsql/ActionWaitForSql.java
@@ -194,11 +194,6 @@ public class ActionWaitForSql extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   public SuccessCondition getSuccessCondition() {
     return successCondition;
   }
diff --git a/plugins/actions/webserviceavailable/src/main/java/org/apache/hop/workflow/actions/webserviceavailable/ActionWebServiceAvailable.java b/plugins/actions/webserviceavailable/src/main/java/org/apache/hop/workflow/actions/webserviceavailable/ActionWebServiceAvailable.java
index 019fd9503c..3ac22e6b43 100644
--- a/plugins/actions/webserviceavailable/src/main/java/org/apache/hop/workflow/actions/webserviceavailable/ActionWebServiceAvailable.java
+++ b/plugins/actions/webserviceavailable/src/main/java/org/apache/hop/workflow/actions/webserviceavailable/ActionWebServiceAvailable.java
@@ -67,12 +67,6 @@ public class ActionWebServiceAvailable extends ActionBase implements Cloneable,
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionWebServiceAvailable je = (ActionWebServiceAvailable) super.clone();
-    return je;
-  }
-
   @Override
   public Result execute(Result previousResult, int nr) {
     Result result = previousResult;
diff --git a/plugins/actions/writetofile/src/main/java/org/apache/hop/workflow/actions/writetofile/ActionWriteToFile.java b/plugins/actions/writetofile/src/main/java/org/apache/hop/workflow/actions/writetofile/ActionWriteToFile.java
index ba8dd3b330..9e1f8be49a 100644
--- a/plugins/actions/writetofile/src/main/java/org/apache/hop/workflow/actions/writetofile/ActionWriteToFile.java
+++ b/plugins/actions/writetofile/src/main/java/org/apache/hop/workflow/actions/writetofile/ActionWriteToFile.java
@@ -87,12 +87,6 @@ public class ActionWriteToFile extends ActionBase implements Cloneable, IAction
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionWriteToFile je = (ActionWriteToFile) super.clone();
-    return je;
-  }
-
   public void setFilename(String filename) {
     this.filename = filename;
   }
diff --git a/plugins/actions/writetolog/src/main/java/org/apache/hop/workflow/actions/writetolog/ActionWriteToLog.java b/plugins/actions/writetolog/src/main/java/org/apache/hop/workflow/actions/writetolog/ActionWriteToLog.java
index cd206145cf..5c6d291355 100644
--- a/plugins/actions/writetolog/src/main/java/org/apache/hop/workflow/actions/writetolog/ActionWriteToLog.java
+++ b/plugins/actions/writetolog/src/main/java/org/apache/hop/workflow/actions/writetolog/ActionWriteToLog.java
@@ -65,12 +65,6 @@ public class ActionWriteToLog extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionWriteToLog action = (ActionWriteToLog) super.clone();
-    return action;
-  }
-
   private class LogWriterObject implements ILoggingObject {
 
     private ILogChannel log;
diff --git a/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/dtdvalidator/DtdValidator.java b/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/dtdvalidator/DtdValidator.java
index 253093ecc2..6143702dcb 100644
--- a/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/dtdvalidator/DtdValidator.java
+++ b/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/dtdvalidator/DtdValidator.java
@@ -70,12 +70,6 @@ public class DtdValidator extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    DtdValidator je = (DtdValidator) super.clone();
-    return je;
-  }
-
   public String getRealxmlfilename() {
     return resolve(xmlFilename);
   }
diff --git a/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/xmlwellformed/XmlWellFormed.java b/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/xmlwellformed/XmlWellFormed.java
index 472071918b..534405b8ea 100644
--- a/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/xmlwellformed/XmlWellFormed.java
+++ b/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/xmlwellformed/XmlWellFormed.java
@@ -139,12 +139,6 @@ public class XmlWellFormed extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    XmlWellFormed je = (XmlWellFormed) super.clone();
-    return je;
-  }
-
   @Override
   public Result execute(Result previousResult, int nr) throws HopException {
     Result result = previousResult;
diff --git a/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/xsdvalidator/XsdValidator.java b/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/xsdvalidator/XsdValidator.java
index 49cc51906d..627735af32 100644
--- a/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/xsdvalidator/XsdValidator.java
+++ b/plugins/actions/xml/src/main/java/org/apache/hop/workflow/actions/xml/xsdvalidator/XsdValidator.java
@@ -105,12 +105,6 @@ public class XsdValidator extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    XsdValidator je = (XsdValidator) super.clone();
-    return je;
-  }
-
   public String getRealxmlfilename() {
     return resolve(getXmlFilename());
   }
diff --git a/plugins/actions/zipfile/src/main/java/org/apache/hop/workflow/actions/zipfile/ActionZipFile.java b/plugins/actions/zipfile/src/main/java/org/apache/hop/workflow/actions/zipfile/ActionZipFile.java
index d0717e3bd8..e3d7f1fb3e 100644
--- a/plugins/actions/zipfile/src/main/java/org/apache/hop/workflow/actions/zipfile/ActionZipFile.java
+++ b/plugins/actions/zipfile/src/main/java/org/apache/hop/workflow/actions/zipfile/ActionZipFile.java
@@ -165,12 +165,6 @@ public class ActionZipFile extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionZipFile je = (ActionZipFile) super.clone();
-    return je;
-  }
-
   @Override
   public boolean isEvaluation() {
     return true;
diff --git a/plugins/databases/access/src/main/java/org/apache/hop/pipeline/transforms/accessoutput/AccessOutputMeta.java b/plugins/databases/access/src/main/java/org/apache/hop/pipeline/transforms/accessoutput/AccessOutputMeta.java
index 4fe36a84ee..b5431e7ae7 100644
--- a/plugins/databases/access/src/main/java/org/apache/hop/pipeline/transforms/accessoutput/AccessOutputMeta.java
+++ b/plugins/databases/access/src/main/java/org/apache/hop/pipeline/transforms/accessoutput/AccessOutputMeta.java
@@ -115,12 +115,6 @@ public class AccessOutputMeta extends BaseTransformMeta<AccessOutput, AccessOutp
     super();
   }
 
-  @Override
-  public Object clone() {
-    AccessOutputMeta retval = (AccessOutputMeta) super.clone();
-    return retval;
-  }
-
   /**
    * @return Returns the tablename.
    */
diff --git a/plugins/databases/as400/src/main/java/org/apache/hop/workflow/actions/as400command/ActionAs400Command.java b/plugins/databases/as400/src/main/java/org/apache/hop/workflow/actions/as400command/ActionAs400Command.java
index d93322ca06..1ec36e8617 100644
--- a/plugins/databases/as400/src/main/java/org/apache/hop/workflow/actions/as400command/ActionAs400Command.java
+++ b/plugins/databases/as400/src/main/java/org/apache/hop/workflow/actions/as400command/ActionAs400Command.java
@@ -94,21 +94,6 @@ public class ActionAs400Command extends ActionBase implements Cloneable, IAction
     this("", "");
   }
 
-  public ActionAs400Command(ActionAs400Command other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.server = other.server;
-    this.user = other.user;
-    this.password = other.password;
-    this.proxyHost = other.proxyHost;
-    this.proxyPort = other.proxyPort;
-    this.command = other.command;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionAs400Command(this);
-  }
-
   /**
    * @return Returns the userName.
    */
diff --git a/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderMeta.java b/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderMeta.java
index e99a6be338..093fae2bac 100644
--- a/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderMeta.java
+++ b/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderMeta.java
@@ -206,11 +206,6 @@ public class CrateDBBulkLoaderMeta
     fields = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   public String getHttpLogin() {
     return httpLogin;
   }
diff --git a/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderMeta.java b/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderMeta.java
index b91326fbfe..5af71d0c5b 100644
--- a/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderMeta.java
+++ b/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderMeta.java
@@ -755,16 +755,6 @@ public class SnowflakeBulkLoaderMeta
     return fileDate;
   }
 
-  /**
-   * Clones the transform so that it can be copied and used in clusters
-   *
-   * @return A copy of the transform
-   */
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   /** Sets the default values for all metadata attributes. */
   @Override
   public void setDefault() {
diff --git a/plugins/databases/snowflake/src/main/java/org/apache/hop/workflow/actions/snowflake/WarehouseManager.java b/plugins/databases/snowflake/src/main/java/org/apache/hop/workflow/actions/snowflake/WarehouseManager.java
index b4de8c896f..0442a4c64d 100644
--- a/plugins/databases/snowflake/src/main/java/org/apache/hop/workflow/actions/snowflake/WarehouseManager.java
+++ b/plugins/databases/snowflake/src/main/java/org/apache/hop/workflow/actions/snowflake/WarehouseManager.java
@@ -170,11 +170,6 @@ public class WarehouseManager extends ActionBase implements Cloneable, IAction {
     failIfNotExists = true;
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   public int getManagementActionId() {
     if (managementAction != null) {
       for (int i = 0; i < MANAGEMENT_ACTIONS.length; i++) {
diff --git a/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastMeta.java b/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastMeta.java
index 3edfb0d3ff..27accff438 100644
--- a/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastMeta.java
+++ b/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastMeta.java
@@ -281,14 +281,4 @@ public class TeraFastMeta extends BaseTransformMeta<ITransform, ITransformData>
     }
     return null;
   }
-
-  /**
-   * {@inheritDoc}
-   *
-   * @see BaseTransformMeta#clone()
-   */
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
 }
diff --git a/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderMeta.java b/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderMeta.java
index 0bf6535ee9..e7778711f4 100644
--- a/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderMeta.java
+++ b/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderMeta.java
@@ -164,11 +164,6 @@ public class VerticaBulkLoaderMeta
     fields = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   /**
    * @return returns the database connection name
    */
diff --git a/plugins/engines/beam/src/main/java/org/apache/hop/beam/transforms/bigtable/BeamBigtableOutputMeta.java b/plugins/engines/beam/src/main/java/org/apache/hop/beam/transforms/bigtable/BeamBigtableOutputMeta.java
index cd84ddf89b..541fb406c8 100644
--- a/plugins/engines/beam/src/main/java/org/apache/hop/beam/transforms/bigtable/BeamBigtableOutputMeta.java
+++ b/plugins/engines/beam/src/main/java/org/apache/hop/beam/transforms/bigtable/BeamBigtableOutputMeta.java
@@ -77,22 +77,6 @@ public class BeamBigtableOutputMeta extends BaseTransformMeta<Dummy, DummyData>
     columns = new ArrayList<>();
   }
 
-  public BeamBigtableOutputMeta(BeamBigtableOutputMeta m) {
-    this();
-    this.projectId = m.projectId;
-    this.instanceId = m.instanceId;
-    this.tableId = m.tableId;
-    this.keyField = m.keyField;
-    for (BigtableColumn column : this.columns) {
-      this.columns.add(new BigtableColumn(column));
-    }
-  }
-
-  @Override
-  public BeamBigtableOutputMeta clone() {
-    return new BeamBigtableOutputMeta(this);
-  }
-
   @Override
   public boolean isInput() {
     return false;
diff --git a/plugins/misc/documentation/src/main/java/org/apache/hop/documentation/ActionDoc.java b/plugins/misc/documentation/src/main/java/org/apache/hop/documentation/ActionDoc.java
index b478bc6060..f154dd16e3 100644
--- a/plugins/misc/documentation/src/main/java/org/apache/hop/documentation/ActionDoc.java
+++ b/plugins/misc/documentation/src/main/java/org/apache/hop/documentation/ActionDoc.java
@@ -103,21 +103,6 @@ public class ActionDoc extends ActionBase implements Cloneable, IAction {
 
   public ActionDoc() {}
 
-  public ActionDoc(ActionDoc other) {
-    super(other.getName(), other.getDescription(), other.getPluginId());
-    this.targetParentFolder = other.targetParentFolder;
-    this.includingNotes = other.includingNotes;
-    this.includingParameters = other.includingParameters;
-    this.includingMetadata = other.includingMetadata;
-    this.generateHtml = other.generateHtml;
-    this.removeMarkdown = other.removeMarkdown;
-  }
-
-  @Override
-  public ActionDoc clone() {
-    return new ActionDoc(this);
-  }
-
   /**
    * Execute this action and return the result. In this case it means, just set the result boolean
    * in the Result class.
diff --git a/plugins/misc/mail/src/main/java/org/apache/hop/mail/pipeline/transforms/mail/MailMeta.java b/plugins/misc/mail/src/main/java/org/apache/hop/mail/pipeline/transforms/mail/MailMeta.java
index f4452fef6a..fb92833de5 100644
--- a/plugins/misc/mail/src/main/java/org/apache/hop/mail/pipeline/transforms/mail/MailMeta.java
+++ b/plugins/misc/mail/src/main/java/org/apache/hop/mail/pipeline/transforms/mail/MailMeta.java
@@ -190,63 +190,6 @@ public class MailMeta extends BaseTransformMeta<Mail, MailData> {
     embeddedImages = new ArrayList<>();
   }
 
-  public MailMeta(MailMeta m) {
-    this();
-    this.addMessageToOutput = m.addMessageToOutput;
-    this.attachContentField = m.attachContentField;
-    this.attachContentFileNameField = m.attachContentFileNameField;
-    this.attachContentFromField = m.attachContentFromField;
-    this.authenticationPassword = m.authenticationPassword;
-    this.authenticationUser = m.authenticationUser;
-    this.checkServerIdentity = m.checkServerIdentity;
-    this.comment = m.comment;
-    this.connectionName = m.connectionName;
-    this.contactPerson = m.contactPerson;
-    this.contactPhone = m.contactPhone;
-    this.destination = m.destination;
-    this.destinationBCc = m.destinationBCc;
-    this.destinationCc = m.destinationCc;
-    this.dynamicFieldName = m.dynamicFieldName;
-    this.dynamicWildcard = m.dynamicWildcard;
-    this.dynamicZipFilename = m.dynamicZipFilename;
-    this.encoding = m.encoding;
-    this.filenameDynamic = m.filenameDynamic;
-    this.importance = m.importance;
-    this.includeDate = m.includeDate;
-    this.includeSubFolders = m.includeSubFolders;
-    this.includingFiles = m.includingFiles;
-    this.messageOutputField = m.messageOutputField;
-    this.onlySendComment = m.onlySendComment;
-    this.port = m.port;
-    this.priority = m.priority;
-    this.replyAddress = m.replyAddress;
-    this.replyName = m.replyName;
-    this.replyToAddresses = m.replyToAddresses;
-    this.secureConnectionType = m.secureConnectionType;
-    this.sensitivity = m.sensitivity;
-    this.server = m.server;
-    this.sourceFileFolderName = m.sourceFileFolderName;
-    this.sourceWildCard = m.sourceWildCard;
-    this.subject = m.subject;
-    this.trustedHosts = m.trustedHosts;
-    this.useHTML = m.useHTML;
-    this.usePriority = m.usePriority;
-    this.useXOAuth2 = m.useXOAuth2;
-    this.usingAuthentication = m.usingAuthentication;
-    this.usingSecureAuthentication = m.usingSecureAuthentication;
-    this.zipFilename = m.zipFilename;
-    this.zipFilenameDynamic = m.zipFilenameDynamic;
-    this.zipFiles = m.zipFiles;
-    this.zipLimitSize = m.zipLimitSize;
-    m.embeddedImages.forEach(
-        imageField -> this.embeddedImages.add(new MailEmbeddedImageField(imageField)));
-  }
-
-  @Override
-  public Object clone() {
-    return new MailMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/misc/mail/src/main/java/org/apache/hop/mail/pipeline/transforms/mailinput/MailInputMeta.java b/plugins/misc/mail/src/main/java/org/apache/hop/mail/pipeline/transforms/mailinput/MailInputMeta.java
index 72da352a81..a81039b887 100644
--- a/plugins/misc/mail/src/main/java/org/apache/hop/mail/pipeline/transforms/mailinput/MailInputMeta.java
+++ b/plugins/misc/mail/src/main/java/org/apache/hop/mail/pipeline/transforms/mailinput/MailInputMeta.java
@@ -197,20 +197,6 @@ public class MailInputMeta extends BaseTransformMeta<MailInput, MailInputData> {
     super(); // allocate BaseTransformMeta
   }
 
-  @Override
-  public Object clone() {
-    MailInputMeta retval = (MailInputMeta) super.clone();
-    List<MailInputField> retvalFields = new ArrayList<>();
-    for (MailInputField inputField : inputFields) {
-      if (inputField != null) {
-        retvalFields.add((MailInputField) inputField.clone());
-      }
-    }
-    retval.setInputFields(retvalFields);
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     serverName = null;
diff --git a/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/getpop/ActionGetPOP.java b/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/getpop/ActionGetPOP.java
index ccc61778ae..38002f99db 100644
--- a/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/getpop/ActionGetPOP.java
+++ b/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/getpop/ActionGetPOP.java
@@ -271,12 +271,6 @@ public class ActionGetPOP extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionGetPOP je = (ActionGetPOP) super.clone();
-    return je;
-  }
-
   public String getRealPort() {
     return resolve(getSslPort());
   }
diff --git a/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/mail/ActionMail.java b/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/mail/ActionMail.java
index 28ccde624b..48dfa13a65 100644
--- a/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/mail/ActionMail.java
+++ b/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/mail/ActionMail.java
@@ -197,16 +197,6 @@ public class ActionMail extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionMail je = (ActionMail) super.clone();
-
-    fileTypes = je.fileTypes;
-    embeddedimages = je.embeddedimages;
-
-    return je;
-  }
-
   @Override
   public Result execute(Result result, int nr) {
     File masterZipfile = null;
diff --git a/plugins/misc/testing/src/main/java/org/apache/hop/testing/actions/runtests/RunPipelineTests.java b/plugins/misc/testing/src/main/java/org/apache/hop/testing/actions/runtests/RunPipelineTests.java
index 078f3af85c..0e087df760 100644
--- a/plugins/misc/testing/src/main/java/org/apache/hop/testing/actions/runtests/RunPipelineTests.java
+++ b/plugins/misc/testing/src/main/java/org/apache/hop/testing/actions/runtests/RunPipelineTests.java
@@ -63,11 +63,6 @@ public class RunPipelineTests extends ActionBase implements IAction, Cloneable {
     this("", "");
   }
 
-  @Override
-  public RunPipelineTests clone() {
-    return (RunPipelineTests) super.clone();
-  }
-
   @Override
   public Result execute(Result prevResult, int nr) throws HopException {
 
diff --git a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avroinput/AvroFileInputMeta.java b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avroinput/AvroFileInputMeta.java
index 66ee470125..eb36a8dfb4 100644
--- a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avroinput/AvroFileInputMeta.java
+++ b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avroinput/AvroFileInputMeta.java
@@ -53,17 +53,6 @@ public class AvroFileInputMeta extends BaseTransformMeta<AvroFileInput, AvroFile
     outputFieldName = "avro";
   }
 
-  public AvroFileInputMeta(AvroFileInputMeta m) {
-    this.outputFieldName = m.outputFieldName;
-    this.dataFilenameField = m.dataFilenameField;
-    this.rowsLimit = m.rowsLimit;
-  }
-
-  @Override
-  public AvroFileInputMeta clone() {
-    return new AvroFileInputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputMeta.java b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputMeta.java
index bdbeac832a..ac4e97968a 100644
--- a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputMeta.java
+++ b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputMeta.java
@@ -400,17 +400,6 @@ public class AvroOutputMeta extends BaseTransformMeta<AvroOutput, AvroOutputData
     this.createSchemaFile = createSchemaFile;
   }
 
-  @Override
-  public Object clone() {
-    AvroOutputMeta retval = new AvroOutputMeta();
-
-    for (AvroOutputField field : outputFields) {
-      retval.getOutputFields().add(new AvroOutputField(field));
-    }
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     createParentFolder = true; // Default createparentfolder to true
diff --git a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sns/SnsNotifyMeta.java b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sns/SnsNotifyMeta.java
index 8b2245f36a..75bcb9f81e 100644
--- a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sns/SnsNotifyMeta.java
+++ b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sns/SnsNotifyMeta.java
@@ -243,22 +243,6 @@ public class SnsNotifyMeta extends BaseTransformMeta<SnsNotify, SnsNotifyData> {
     this.tFldMessageID = tFldMessageID;
   }
 
-  /**
-   * This method is used when a transform is duplicated in hop gui. It needs to return a deep copy
-   * of this transform's meta object. Be sure to create proper deep copies if the transform
-   * configuration is stored in modifiable objects.
-   *
-   * <p>See org.apache.hop.pipeline.transforms.rowgenerator.RowGeneratorMeta.clone() for an example
-   * on creating a deep copy.
-   *
-   * @return a deep copy of this
-   */
-  @Override
-  public Object clone() {
-    Object retval = super.clone();
-    return retval;
-  }
-
   /**
    * This method is called to determine the changes the transform is making to the row-stream. To
    * that end a IRowMeta object is passed in, containing the row-stream structure as it is when
diff --git a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sqs/SqsReaderMeta.java b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sqs/SqsReaderMeta.java
index 471a08a820..9f7153f28c 100644
--- a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sqs/SqsReaderMeta.java
+++ b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sqs/SqsReaderMeta.java
@@ -187,22 +187,6 @@ public class SqsReaderMeta extends BaseTransformMeta<SqsReader, SqsReaderData> {
     this.tFldMaxMessages = tFldMaxMessages;
   }
 
-  /**
-   * This method is used when a transform is duplicated in Hop Gui. It needs to return a deep copy
-   * of this transform meta object. Be sure to create proper deep copies if the transform
-   * configuration is stored in modifiable objects.
-   *
-   * <p>See org.apache.hop.pipeline.transforms.rowgenerator.RowGeneratorMeta.clone() for an example
-   * on creating a deep copy.
-   *
-   * @return a deep copy of this
-   */
-  @Override
-  public Object clone() {
-    Object retval = super.clone();
-    return retval;
-  }
-
   /**
    * This method is called to determine the changes the transform is making to the row-stream. To
    * that end a RowMetaInterface object is passed in, containing the row-stream structure as it is
diff --git a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderMeta.java b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderMeta.java
index d443a8a2db..524a4b93cf 100644
--- a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderMeta.java
+++ b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderMeta.java
@@ -201,11 +201,6 @@ public class RedshiftBulkLoaderMeta
     fields = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   /**
    * @return returns the database connection name
    */
diff --git a/plugins/tech/azure/src/main/java/org/apache/hop/pipeline/transforms/eventhubs/listen/AzureListenerMeta.java b/plugins/tech/azure/src/main/java/org/apache/hop/pipeline/transforms/eventhubs/listen/AzureListenerMeta.java
index c3713b9e7c..88ab798618 100644
--- a/plugins/tech/azure/src/main/java/org/apache/hop/pipeline/transforms/eventhubs/listen/AzureListenerMeta.java
+++ b/plugins/tech/azure/src/main/java/org/apache/hop/pipeline/transforms/eventhubs/listen/AzureListenerMeta.java
@@ -104,34 +104,6 @@ public class AzureListenerMeta extends BaseTransformMeta<AzureListener, AzureLis
     super();
   }
 
-  public AzureListenerMeta(AzureListenerMeta m) {
-    this();
-    this.namespace = m.namespace;
-    this.eventHubName = m.eventHubName;
-    this.sasKeyName = m.sasKeyName;
-    this.sasKey = m.sasKey;
-    this.consumerGroupName = m.consumerGroupName;
-    this.storageConnectionString = m.storageConnectionString;
-    this.storageContainerName = m.storageContainerName;
-    this.prefetchSize = m.prefetchSize;
-    this.batchSize = m.batchSize;
-    this.outputField = m.outputField;
-    this.partitionIdField = m.partitionIdField;
-    this.offsetField = m.offsetField;
-    this.sequenceNumberField = m.sequenceNumberField;
-    this.hostField = m.hostField;
-    this.enqueuedTimeField = m.enqueuedTimeField;
-    this.batchPipeline = m.batchPipeline;
-    this.batchInputTransform = m.batchInputTransform;
-    this.batchOutputTransform = m.batchOutputTransform;
-    this.batchMaxWaitTime = m.batchMaxWaitTime;
-  }
-
-  @Override
-  public AzureListenerMeta clone() {
-    return new AzureListenerMeta(this);
-  }
-
   @Override
   public void setDefault() {
     consumerGroupName = "$Default";
diff --git a/plugins/tech/azure/src/main/java/org/apache/hop/pipeline/transforms/eventhubs/write/AzureWriterMeta.java b/plugins/tech/azure/src/main/java/org/apache/hop/pipeline/transforms/eventhubs/write/AzureWriterMeta.java
index a328beda5d..64ea7a5f3d 100644
--- a/plugins/tech/azure/src/main/java/org/apache/hop/pipeline/transforms/eventhubs/write/AzureWriterMeta.java
+++ b/plugins/tech/azure/src/main/java/org/apache/hop/pipeline/transforms/eventhubs/write/AzureWriterMeta.java
@@ -58,20 +58,6 @@ public class AzureWriterMeta extends BaseTransformMeta<AzureWrite, AzureWriterDa
     super();
   }
 
-  public AzureWriterMeta(AzureWriterMeta m) {
-    this.namespace = m.namespace;
-    this.eventHubName = m.eventHubName;
-    this.sasKeyName = m.sasKeyName;
-    this.sasKey = m.sasKey;
-    this.batchSize = m.batchSize;
-    this.messageField = m.messageField;
-  }
-
-  @Override
-  public AzureWriterMeta clone() {
-    return new AzureWriterMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobRun.java b/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobRun.java
index 26df204911..307ad068c0 100644
--- a/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobRun.java
+++ b/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobRun.java
@@ -232,11 +232,6 @@ public class ActionDatabricksJobRun extends ActionBase implements Cloneable, IAc
     this("");
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   public void setClientFactory(ClientFactory clientFactory) {
     this.clientFactory = clientFactory != null ? clientFactory : RestDatabricksJobsClient::create;
   }
diff --git a/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobWait.java b/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobWait.java
index 5384e0953d..7a952af05a 100644
--- a/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobWait.java
+++ b/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobWait.java
@@ -103,11 +103,6 @@ public class ActionDatabricksJobWait extends ActionBase implements Cloneable, IA
     this("");
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   public void setClientFactory(ActionDatabricksJobRun.ClientFactory clientFactory) {
     this.clientFactory = clientFactory != null ? clientFactory : RestDatabricksJobsClient::create;
   }
diff --git a/plugins/tech/ftp/src/main/java/org/apache/hop/workflow/actions/ftpdelete/ActionFtpDelete.java b/plugins/tech/ftp/src/main/java/org/apache/hop/workflow/actions/ftpdelete/ActionFtpDelete.java
index 66564f7336..9bf4846e4a 100644
--- a/plugins/tech/ftp/src/main/java/org/apache/hop/workflow/actions/ftpdelete/ActionFtpDelete.java
+++ b/plugins/tech/ftp/src/main/java/org/apache/hop/workflow/actions/ftpdelete/ActionFtpDelete.java
@@ -217,11 +217,6 @@ public class ActionFtpDelete extends ActionBase implements Cloneable, IAction, I
     this.copyPrevious = a.copyPrevious;
   }
 
-  @Override
-  public Object clone() {
-    return new ActionFtpDelete(this);
-  }
-
   @Override
   public String getFtpConnectionName() {
     return Const.NVL(getName(), "FTP Delete");
diff --git a/plugins/tech/ftp/src/main/java/org/apache/hop/workflow/actions/ftpput/ActionFtpPut.java b/plugins/tech/ftp/src/main/java/org/apache/hop/workflow/actions/ftpput/ActionFtpPut.java
index 08e882921f..44c96de2d5 100644
--- a/plugins/tech/ftp/src/main/java/org/apache/hop/workflow/actions/ftpput/ActionFtpPut.java
+++ b/plugins/tech/ftp/src/main/java/org/apache/hop/workflow/actions/ftpput/ActionFtpPut.java
@@ -187,12 +187,6 @@ public class ActionFtpPut extends ActionBase implements Cloneable, IAction, IFtp
     this.socksProxyPassword = a.socksProxyPassword;
   }
 
-  @Override
-  @SuppressWarnings("java:S2975")
-  public ActionFtpPut clone() {
-    return new ActionFtpPut(this);
-  }
-
   @Override
   public String getFtpConnectionName() {
     return Const.NVL(getName(), "FTP Put");
diff --git a/plugins/tech/google/src/main/java/org/apache/hop/pipeline/transforms/googlesheets/GoogleSheetsOutputMeta.java b/plugins/tech/google/src/main/java/org/apache/hop/pipeline/transforms/googlesheets/GoogleSheetsOutputMeta.java
index c7a0b67921..0364f89482 100644
--- a/plugins/tech/google/src/main/java/org/apache/hop/pipeline/transforms/googlesheets/GoogleSheetsOutputMeta.java
+++ b/plugins/tech/google/src/main/java/org/apache/hop/pipeline/transforms/googlesheets/GoogleSheetsOutputMeta.java
@@ -109,21 +109,6 @@ public class GoogleSheetsOutputMeta
     this.retryDelayMs = "2";
   }
 
-  @Override
-  public Object clone() {
-    GoogleSheetsOutputMeta retval = (GoogleSheetsOutputMeta) super.clone();
-    retval.setJsonCredentialPath(this.jsonCredentialPath);
-    retval.setSpreadsheetKey(this.spreadsheetKey);
-    retval.setWorksheetId(this.worksheetId);
-    retval.setCreate(this.create);
-    retval.setAppend(this.append);
-    retval.setShareEmail(this.shareEmail);
-    retval.setShareDomain(this.shareDomain);
-    retval.setRetryAttempts(this.retryAttempts);
-    retval.setRetryDelayMs(this.retryDelayMs);
-    return retval;
-  }
-
   @Override
   public void check(
       List<ICheckResult> remarks,
diff --git a/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbinput/MongoDbInputMeta.java b/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbinput/MongoDbInputMeta.java
index b3ca9257df..0ad4565b16 100644
--- a/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbinput/MongoDbInputMeta.java
+++ b/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbinput/MongoDbInputMeta.java
@@ -73,12 +73,6 @@ public class MongoDbInputMeta extends MongoDbMeta<MongoDbInput, MongoDbInputData
   @HopMetadataProperty(key = "execute_for_each_row", injectionKey = "EXECUTE_FOR_EACH_ROW")
   private boolean executeForEachIncomingRow = false;
 
-  @Override
-  public Object clone() {
-    MongoDbInputMeta meta = (MongoDbInputMeta) super.clone();
-    return meta;
-  }
-
   @Override
   public void setDefault() {
     jsonFieldName = "json";
diff --git a/plugins/tech/mongodb/src/main/java/org/apache/hop/workflow/actions/mql/ActionMql.java b/plugins/tech/mongodb/src/main/java/org/apache/hop/workflow/actions/mql/ActionMql.java
index 331334e86e..2cd1854bde 100644
--- a/plugins/tech/mongodb/src/main/java/org/apache/hop/workflow/actions/mql/ActionMql.java
+++ b/plugins/tech/mongodb/src/main/java/org/apache/hop/workflow/actions/mql/ActionMql.java
@@ -78,12 +78,6 @@ public class ActionMql extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionMql je = (ActionMql) super.clone();
-    return je;
-  }
-
   public void setMql(String mql) {
     this.mql = mql;
   }
diff --git a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/actions/cypherscript/CypherScript.java b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/actions/cypherscript/CypherScript.java
index d0500d1376..4b098c5825 100644
--- a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/actions/cypherscript/CypherScript.java
+++ b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/actions/cypherscript/CypherScript.java
@@ -63,18 +63,6 @@ public class CypherScript extends ActionBase implements IAction {
     super(name, description);
   }
 
-  public CypherScript(CypherScript s) {
-    super(s.getName(), s.getDescription(), s.getPluginId());
-    this.connectionName = s.connectionName;
-    this.script = s.script;
-    this.replacingVariables = s.replacingVariables;
-  }
-
-  @Override
-  public CypherScript clone() {
-    return new CypherScript(this);
-  }
-
   @Override
   public Result execute(Result result, int nr) throws HopException {
     IHopMetadataSerializer<NeoConnection> serializer =
diff --git a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypher/CypherMeta.java b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypher/CypherMeta.java
index c718181116..197e803492 100644
--- a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypher/CypherMeta.java
+++ b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypher/CypherMeta.java
@@ -137,29 +137,6 @@ public class CypherMeta extends BaseTransformMeta<Cypher, CypherData> {
     returnValues = new ArrayList<>();
   }
 
-  public CypherMeta(CypherMeta m) {
-    this();
-    this.connectionName = m.connectionName;
-    this.cypher = m.cypher;
-    this.batchSize = m.batchSize;
-    this.readOnly = m.readOnly;
-    this.retryingOnDisconnect = m.retryingOnDisconnect;
-    this.nrRetriesOnError = m.nrRetriesOnError;
-    this.cypherFromField = m.cypherFromField;
-    this.cypherField = m.cypherField;
-    this.usingUnwind = m.usingUnwind;
-    this.unwindMapName = m.unwindMapName;
-    this.returningGraph = m.returningGraph;
-    this.returnGraphField = m.returnGraphField;
-    m.parameterMappings.forEach(p -> this.parameterMappings.add(new ParameterMapping(p)));
-    m.returnValues.forEach(v -> this.returnValues.add(new ReturnValue(v)));
-  }
-
-  @Override
-  public CypherMeta clone() {
-    return new CypherMeta(this);
-  }
-
   @Override
   public void setDefault() {
     retryingOnDisconnect = true;
diff --git a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypherbuilder/CypherBuilderDialog.java b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypherbuilder/CypherBuilderDialog.java
index 7f431f4b74..0dcbbed5cd 100644
--- a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypherbuilder/CypherBuilderDialog.java
+++ b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypherbuilder/CypherBuilderDialog.java
@@ -127,7 +127,7 @@ public class CypherBuilderDialog extends BaseTransformDialog {
     super(parent, variables, transformMeta, pipelineMeta);
     input = transformMeta;
 
-    this.copy = input.clone();
+    this.copy = (CypherBuilderMeta) input.clone();
   }
 
   @Override
diff --git a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypherbuilder/CypherBuilderMeta.java b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypherbuilder/CypherBuilderMeta.java
index 4205c24f7a..d225600fd4 100644
--- a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypherbuilder/CypherBuilderMeta.java
+++ b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/cypherbuilder/CypherBuilderMeta.java
@@ -74,16 +74,6 @@ public class CypherBuilderMeta extends BaseTransformMeta<CypherBuilder, CypherBu
     this.operations = new ArrayList<>();
   }
 
-  public CypherBuilderMeta(CypherBuilderMeta meta) {
-    this();
-    this.connectionName = meta.connectionName;
-    this.batchSize = meta.batchSize;
-    this.unwindAlias = meta.unwindAlias;
-    this.retries = meta.retries;
-    meta.parameters.forEach(p -> this.parameters.add(p.clone()));
-    meta.operations.forEach(o -> this.operations.add(o.clone()));
-  }
-
   @Override
   public void setDefault() {
     batchSize = "1000";
@@ -156,11 +146,6 @@ public class CypherBuilderMeta extends BaseTransformMeta<CypherBuilder, CypherBu
     return false;
   }
 
-  @Override
-  public CypherBuilderMeta clone() {
-    return new CypherBuilderMeta(this);
-  }
-
   public IOperation findOperation(String operationName) {
     for (IOperation operation : operations) {
       if (operation.getName() != null && operation.getName().equals(operationName)) {
diff --git a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/loginfo/GetLoggingInfoMeta.java b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/loginfo/GetLoggingInfoMeta.java
index 5c091cddfb..b6f7b6bbff 100644
--- a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/loginfo/GetLoggingInfoMeta.java
+++ b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/loginfo/GetLoggingInfoMeta.java
@@ -65,13 +65,6 @@ public class GetLoggingInfoMeta extends BaseTransformMeta<GetLoggingInfo, GetLog
     fields = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    GetLoggingInfoMeta retval = (GetLoggingInfoMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
 
diff --git a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/output/Neo4JOutputMeta.java b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/output/Neo4JOutputMeta.java
index e8ad04e7d6..4eb559b9de 100644
--- a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/output/Neo4JOutputMeta.java
+++ b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/transforms/output/Neo4JOutputMeta.java
@@ -180,11 +180,6 @@ public class Neo4JOutputMeta extends BaseTransformMeta<Neo4JOutput, Neo4JOutputD
     }
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   public boolean dynamicFromLabels() {
     return dynamicLabels(nodeFromField.getLabels());
   }
diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforce/SalesforceTransformMeta.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforce/SalesforceTransformMeta.java
index 76e47fd3b8..1eec33ca22 100644
--- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforce/SalesforceTransformMeta.java
+++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforce/SalesforceTransformMeta.java
@@ -92,12 +92,6 @@ public abstract class SalesforceTransformMeta<
       hopMetadataPropertyType = HopMetadataPropertyType.SALESFORCE_CONNECTION)
   private String salesforceConnection;
 
-  @Override
-  public Object clone() {
-    SalesforceTransformMeta retval = (SalesforceTransformMeta) super.clone();
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     setTargetUrl(SalesforceConnectionUtils.TARGET_DEFAULT_URL);
diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforcedelete/SalesforceDeleteMeta.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforcedelete/SalesforceDeleteMeta.java
index a9151db73d..44f941c713 100644
--- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforcedelete/SalesforceDeleteMeta.java
+++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforcedelete/SalesforceDeleteMeta.java
@@ -109,13 +109,6 @@ public class SalesforceDeleteMeta
     return Const.toInt(this.batchSize, 10);
   }
 
-  @Override
-  public Object clone() {
-    SalesforceDeleteMeta retval = (SalesforceDeleteMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     super.setDefault();
diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinput/SalesforceInputMeta.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinput/SalesforceInputMeta.java
index c1e3d25ee8..63fb1bc3d2 100644
--- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinput/SalesforceInputMeta.java
+++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinput/SalesforceInputMeta.java
@@ -259,25 +259,6 @@ public class SalesforceInputMeta
     return includeDeletionDate;
   }
 
-  @Override
-  public Object clone() {
-    SalesforceInputMeta retval = (SalesforceInputMeta) super.clone();
-    retval.fields = new ArrayList<>();
-
-    int nrFields = fields.size();
-
-    //    retval.allocate(nrFields);
-
-    for (int i = 0; i < nrFields; i++) {
-      if (fields.get(i) != null) {
-        //        retval.inputFields.get(i) = (SalesforceInputField) inputFields.get(i).clone();
-        retval.fields.add((SalesforceInputField) fields.get(i).clone());
-      }
-    }
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     super.setDefault();
diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinsert/SalesforceInsertMeta.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinsert/SalesforceInsertMeta.java
index 82ffb49518..af24079e42 100644
--- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinsert/SalesforceInsertMeta.java
+++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinsert/SalesforceInsertMeta.java
@@ -72,21 +72,6 @@ public class SalesforceInsertMeta
     return Const.toInt(this.batchSize, 10);
   }
 
-  @Override
-  public Object clone() {
-    SalesforceInsertMeta retval = (SalesforceInsertMeta) super.clone();
-    retval.fields = new ArrayList<>();
-    int nrFields = fields.size();
-    for (int i = 0; i < fields.size(); i++) {
-      if (fields.get(i) != null) {
-        //        retval.inputFields.get(i) = (SalesforceInputField) inputFields.get(i).clone();
-        retval.fields.add((SalesforceInsertField) fields.get(i).clone());
-      }
-    }
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     super.setDefault();
diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupdate/SalesforceUpdateMeta.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupdate/SalesforceUpdateMeta.java
index 50d7704462..09531acc6b 100644
--- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupdate/SalesforceUpdateMeta.java
+++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupdate/SalesforceUpdateMeta.java
@@ -68,23 +68,6 @@ public class SalesforceUpdateMeta
     return Const.toInt(this.batchSize, 10);
   }
 
-  @Override
-  public Object clone() {
-    SalesforceUpdateMeta retval = (SalesforceUpdateMeta) super.clone();
-
-    // Initialize the fields list
-    retval.fields = new ArrayList<>();
-
-    for (int i = 0; i < fields.size(); i++) {
-      if (fields.get(i) != null) {
-        //        retval.inputFields.get(i) = (SalesforceInputField) inputFields.get(i).clone();
-        retval.fields.add((SalesforceInsertField) fields.get(i).clone());
-      }
-    }
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     super.setDefault();
diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupsert/SalesforceUpsertMeta.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupsert/SalesforceUpsertMeta.java
index b4c07793af..ac0e95728b 100644
--- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupsert/SalesforceUpsertMeta.java
+++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupsert/SalesforceUpsertMeta.java
@@ -76,22 +76,6 @@ public class SalesforceUpsertMeta
     return Const.toInt(this.batchSize, 10);
   }
 
-  @Override
-  public Object clone() {
-    SalesforceUpsertMeta retval = (SalesforceUpsertMeta) super.clone();
-
-    // Initialize the fields list
-    retval.fields = new ArrayList<>();
-
-    for (int i = 0; i < fields.size(); i++) {
-      if (fields.get(i) != null) {
-        //        retval.inputFields.get(i) = (SalesforceInputField) inputFields.get(i).clone();
-        retval.fields.add((SalesforceInsertField) fields.get(i).clone());
-      }
-    }
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     super.setDefault();
diff --git a/plugins/tech/sftp/src/main/java/org/apache/hop/workflow/actions/sftp/ActionSftp.java b/plugins/tech/sftp/src/main/java/org/apache/hop/workflow/actions/sftp/ActionSftp.java
index 623baa867a..4c956e9114 100644
--- a/plugins/tech/sftp/src/main/java/org/apache/hop/workflow/actions/sftp/ActionSftp.java
+++ b/plugins/tech/sftp/src/main/java/org/apache/hop/workflow/actions/sftp/ActionSftp.java
@@ -169,37 +169,6 @@ public class ActionSftp extends ActionBase implements Cloneable, IAction {
     this("");
   }
 
-  public ActionSftp(ActionSftp a) {
-    super(a);
-    this.connection = a.connection;
-    this.serverName = a.serverName;
-    this.serverPort = a.serverPort;
-    this.userName = a.userName;
-    this.password = a.password;
-    this.sftpDirectory = a.sftpDirectory;
-    this.targetDirectory = a.targetDirectory;
-    this.wildcard = a.wildcard;
-    this.remove = a.remove;
-    this.addFilenameToResult = a.addFilenameToResult;
-    this.createTargetFolder = a.createTargetFolder;
-    this.copyPrevious = a.copyPrevious;
-    this.useKeyFilename = a.useKeyFilename;
-    this.preserveTargetFileTimestamp = a.preserveTargetFileTimestamp;
-    this.keyFilename = a.keyFilename;
-    this.keyPassPhrase = a.keyPassPhrase;
-    this.compression = a.compression;
-    this.proxyType = a.proxyType;
-    this.proxyHost = a.proxyHost;
-    this.proxyPort = a.proxyPort;
-    this.proxyUsername = a.proxyUsername;
-    this.proxyPassword = a.proxyPassword;
-  }
-
-  @Override
-  public Object clone() {
-    return new ActionSftp(this);
-  }
-
   /** Whether this action gets its server settings from a named SFTP connection. */
   public boolean isUsingConnection() {
     return StringUtils.isNotEmpty(connection);
diff --git a/plugins/tech/sftp/src/main/java/org/apache/hop/workflow/actions/sftpput/ActionSftpPut.java b/plugins/tech/sftp/src/main/java/org/apache/hop/workflow/actions/sftpput/ActionSftpPut.java
index 27fb89a95c..10062d712a 100644
--- a/plugins/tech/sftp/src/main/java/org/apache/hop/workflow/actions/sftpput/ActionSftpPut.java
+++ b/plugins/tech/sftp/src/main/java/org/apache/hop/workflow/actions/sftpput/ActionSftpPut.java
@@ -219,11 +219,6 @@ public class ActionSftpPut extends ActionBase implements Cloneable, IAction {
     }
   }
 
-  @Override
-  public Object clone() {
-    return new ActionSftpPut(this);
-  }
-
   /** Whether this action gets its server settings from a named SFTP connection. */
   public boolean isUsingConnection() {
     return StringUtils.isNotEmpty(connection);
diff --git a/plugins/transforms/binaryfileoutput/src/main/java/org/apache/hop/pipeline/transforms/binaryfileoutput/BinaryFileOutputMeta.java b/plugins/transforms/binaryfileoutput/src/main/java/org/apache/hop/pipeline/transforms/binaryfileoutput/BinaryFileOutputMeta.java
index b38697d6cf..e19daa8c34 100644
--- a/plugins/transforms/binaryfileoutput/src/main/java/org/apache/hop/pipeline/transforms/binaryfileoutput/BinaryFileOutputMeta.java
+++ b/plugins/transforms/binaryfileoutput/src/main/java/org/apache/hop/pipeline/transforms/binaryfileoutput/BinaryFileOutputMeta.java
@@ -86,11 +86,6 @@ public class BinaryFileOutputMeta
     super();
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   @Override
   public void setDefault() {
     binaryField = null;
diff --git a/plugins/transforms/blockuntiltransformsfinish/src/main/java/org/apache/hop/pipeline/transforms/blockuntiltransformsfinish/BlockUntilTransformsFinishMeta.java b/plugins/transforms/blockuntiltransformsfinish/src/main/java/org/apache/hop/pipeline/transforms/blockuntiltransformsfinish/BlockUntilTransformsFinishMeta.java
index ac434c02c6..783273eade 100644
--- a/plugins/transforms/blockuntiltransformsfinish/src/main/java/org/apache/hop/pipeline/transforms/blockuntiltransformsfinish/BlockUntilTransformsFinishMeta.java
+++ b/plugins/transforms/blockuntiltransformsfinish/src/main/java/org/apache/hop/pipeline/transforms/blockuntiltransformsfinish/BlockUntilTransformsFinishMeta.java
@@ -52,15 +52,6 @@ public class BlockUntilTransformsFinishMeta
     blockingTransforms = new ArrayList<>();
   }
 
-  @Override
-  public BlockUntilTransformsFinishMeta clone() {
-    BlockUntilTransformsFinishMeta meta = new BlockUntilTransformsFinishMeta();
-    for (BlockingTransform blockingTransform : blockingTransforms) {
-      meta.blockingTransforms.add(new BlockingTransform(blockingTransform));
-    }
-    return meta;
-  }
-
   @Override
   public void check(
       List<ICheckResult> remarks,
diff --git a/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java b/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java
index f7cb205f24..eff630fedc 100644
--- a/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java
+++ b/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java
@@ -67,7 +67,7 @@ public class CalculatorDialog extends BaseTransformDialog {
 
     // The order here is important... currentMeta is looked at for changes
     currentMeta = transformMeta;
-    originalMeta = transformMeta.clone();
+    originalMeta = (CalculatorMeta) transformMeta.clone();
   }
 
   @Override
diff --git a/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorMeta.java b/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorMeta.java
index de993ed619..232327b07b 100644
--- a/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorMeta.java
+++ b/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorMeta.java
@@ -68,18 +68,6 @@ public class CalculatorMeta extends BaseTransformMeta<Calculator, CalculatorData
     this.functions = new ArrayList<>();
   }
 
-  @Override
-  public CalculatorMeta clone() {
-    CalculatorMeta meta = new CalculatorMeta();
-    meta.setFailIfNoFile(isFailIfNoFile());
-
-    for (CalculatorMetaFunction function : functions) {
-      meta.getFunctions().add(new CalculatorMetaFunction(function));
-    }
-
-    return meta;
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/changefileencoding/src/main/java/org/apache/hop/pipeline/transforms/changefileencoding/ChangeFileEncodingMeta.java b/plugins/transforms/changefileencoding/src/main/java/org/apache/hop/pipeline/transforms/changefileencoding/ChangeFileEncodingMeta.java
index 48eff154dc..0cfeda8688 100644
--- a/plugins/transforms/changefileencoding/src/main/java/org/apache/hop/pipeline/transforms/changefileencoding/ChangeFileEncodingMeta.java
+++ b/plugins/transforms/changefileencoding/src/main/java/org/apache/hop/pipeline/transforms/changefileencoding/ChangeFileEncodingMeta.java
@@ -164,13 +164,6 @@ public class ChangeFileEncodingMeta
     this.createParentFolder = createparentfolder;
   }
 
-  @Override
-  public Object clone() {
-    ChangeFileEncodingMeta retval = (ChangeFileEncodingMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     addSourceResultFilenames = false;
diff --git a/plugins/transforms/checksum/src/main/java/org/apache/hop/pipeline/transforms/checksum/CheckSumMeta.java b/plugins/transforms/checksum/src/main/java/org/apache/hop/pipeline/transforms/checksum/CheckSumMeta.java
index 6b74f6e0e7..f62528bbb5 100644
--- a/plugins/transforms/checksum/src/main/java/org/apache/hop/pipeline/transforms/checksum/CheckSumMeta.java
+++ b/plugins/transforms/checksum/src/main/java/org/apache/hop/pipeline/transforms/checksum/CheckSumMeta.java
@@ -212,21 +212,6 @@ public class CheckSumMeta extends BaseTransformMeta<CheckSum, CheckSumData> {
     resultType = ResultType.STRING;
   }
 
-  @Override
-  public CheckSumMeta clone() {
-    CheckSumMeta meta = new CheckSumMeta();
-    meta.checkSumType = checkSumType;
-    meta.resultFieldName = resultFieldName;
-    meta.resultType = resultType;
-    meta.separator = separator;
-    meta.prefix = prefix;
-    meta.suffix = suffix;
-    for (Field field : fields) {
-      meta.fields.add(new Field(field));
-    }
-    return meta;
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/closure/src/main/java/org/apache/hop/pipeline/transforms/closure/ClosureGeneratorMeta.java b/plugins/transforms/closure/src/main/java/org/apache/hop/pipeline/transforms/closure/ClosureGeneratorMeta.java
index a87871f54a..48fa2de064 100644
--- a/plugins/transforms/closure/src/main/java/org/apache/hop/pipeline/transforms/closure/ClosureGeneratorMeta.java
+++ b/plugins/transforms/closure/src/main/java/org/apache/hop/pipeline/transforms/closure/ClosureGeneratorMeta.java
@@ -60,18 +60,6 @@ public class ClosureGeneratorMeta
     super();
   }
 
-  public ClosureGeneratorMeta(ClosureGeneratorMeta m) {
-    this.rootIdZero = m.rootIdZero;
-    this.parentIdFieldName = m.parentIdFieldName;
-    this.childIdFieldName = m.childIdFieldName;
-    this.distanceFieldName = m.distanceFieldName;
-  }
-
-  @Override
-  public ClosureGeneratorMeta clone() {
-    return new ClosureGeneratorMeta(this);
-  }
-
   @Override
   public void setDefault() {
     // Do nothing
diff --git a/plugins/transforms/coalesce/src/main/java/org/apache/hop/pipeline/transforms/coalesce/CoalesceMeta.java b/plugins/transforms/coalesce/src/main/java/org/apache/hop/pipeline/transforms/coalesce/CoalesceMeta.java
index 02939ad58c..d77396a9d3 100644
--- a/plugins/transforms/coalesce/src/main/java/org/apache/hop/pipeline/transforms/coalesce/CoalesceMeta.java
+++ b/plugins/transforms/coalesce/src/main/java/org/apache/hop/pipeline/transforms/coalesce/CoalesceMeta.java
@@ -70,14 +70,6 @@ public class CoalesceMeta extends BaseTransformMeta<CoalesceTransform, CoalesceD
     fields = new ArrayList<>();
   }
 
-  public CoalesceMeta(CoalesceMeta c) {
-    super();
-    this.treatEmptyStringsAsNulls = c.treatEmptyStringsAsNulls;
-    for (CoalesceField field : c.getFields()) {
-      fields.add(new CoalesceField(field));
-    }
-  }
-
   @Override
   public void setDefault() {
     this.fields = new ArrayList<>();
@@ -92,11 +84,6 @@ public class CoalesceMeta extends BaseTransformMeta<CoalesceTransform, CoalesceD
     this.treatEmptyStringsAsNulls = value;
   }
 
-  @Override
-  public Object clone() {
-    return new CoalesceMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/columnexists/src/main/java/org/apache/hop/pipeline/transforms/columnexists/ColumnExistsMeta.java b/plugins/transforms/columnexists/src/main/java/org/apache/hop/pipeline/transforms/columnexists/ColumnExistsMeta.java
index f5fc6defc3..49e3652ff5 100644
--- a/plugins/transforms/columnexists/src/main/java/org/apache/hop/pipeline/transforms/columnexists/ColumnExistsMeta.java
+++ b/plugins/transforms/columnexists/src/main/java/org/apache/hop/pipeline/transforms/columnexists/ColumnExistsMeta.java
@@ -186,13 +186,6 @@ public class ColumnExistsMeta extends BaseTransformMeta<ColumnExists, ColumnExis
     this.databaseName = databaseName;
   }
 
-  @Override
-  public Object clone() {
-    ColumnExistsMeta retval = (ColumnExistsMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     databaseName = null;
diff --git a/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupMeta.java b/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupMeta.java
index deb99f9450..146e4ea688 100644
--- a/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupMeta.java
+++ b/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupMeta.java
@@ -148,16 +148,6 @@ public class CombinationLookupMeta
     this.fields = new CFields();
   }
 
-  public CombinationLookupMeta(CombinationLookupMeta m) {
-    fields = new CFields();
-  }
-
-  @Override
-  public Object clone() {
-    CombinationLookupMeta retval = (CombinationLookupMeta) super.clone();
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     schemaName = "";
diff --git a/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsMeta.java b/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsMeta.java
index 3a75945044..8f320ffcbf 100644
--- a/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsMeta.java
+++ b/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsMeta.java
@@ -84,16 +84,6 @@ public class ConcatFieldsMeta extends BaseTransformMeta<ConcatFields, ConcatFiel
     extraFields = new ExtraFields();
   }
 
-  public ConcatFieldsMeta(ConcatFieldsMeta m) {
-    this();
-    this.separator = m.separator;
-    this.enclosure = m.enclosure;
-    this.extraFields = new ExtraFields(m.extraFields);
-    for (ConcatField field : outputFields) {
-      outputFields.add(new ConcatField(field));
-    }
-  }
-
   @Override
   public void setDefault() {
     separator = ";";
diff --git a/plugins/transforms/constant/src/main/java/org/apache/hop/pipeline/transforms/constant/ConstantMeta.java b/plugins/transforms/constant/src/main/java/org/apache/hop/pipeline/transforms/constant/ConstantMeta.java
index 4fb95c3281..14da37e308 100644
--- a/plugins/transforms/constant/src/main/java/org/apache/hop/pipeline/transforms/constant/ConstantMeta.java
+++ b/plugins/transforms/constant/src/main/java/org/apache/hop/pipeline/transforms/constant/ConstantMeta.java
@@ -68,11 +68,6 @@ public class ConstantMeta extends BaseTransformMeta<Constant, ConstantData> {
     this.fields = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    return (ConstantMeta) super.clone();
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/constant/src/test/java/org/apache/hop/pipeline/transforms/constant/ConstantChangeDetectionTest.java b/plugins/transforms/constant/src/test/java/org/apache/hop/pipeline/transforms/constant/ConstantChangeDetectionTest.java
new file mode 100644
index 0000000000..6bde2bba6a
--- /dev/null
+++ b/plugins/transforms/constant/src/test/java/org/apache/hop/pipeline/transforms/constant/ConstantChangeDetectionTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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
+ *
+ *      http://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.hop.pipeline.transforms.constant;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Reproduces issue #8022: HopGuiPipelineTransformDelegate.editTransform() decides whether a
+ * transform was edited by comparing TransformMeta.getXml() of a clone taken before the dialog
+ * opened against a clone taken after OK. ConstantMeta.clone() is a shallow Object.clone(), so the
+ * "before" snapshot shares the very same List instance as the live meta. ConstantDialog.ok()
+ * mutates that list in place, so both snapshots serialize identically and the edit is lost.
+ */
+class ConstantChangeDetectionTest {
+
+  @BeforeAll
+  static void setUpBeforeClass() throws Exception {
+    HopEnvironment.init();
+  }
+
+  private static TransformMeta constantTransform() {
+    ConstantMeta meta = new ConstantMeta();
+    meta.getFields().add(new ConstantField("a", "String", "one"));
+    TransformMeta transformMeta = new TransformMeta("Add constants", meta);
+    transformMeta.setTransformPluginId("Constant");
+    return transformMeta;
+  }
+
+  /** Exactly what the delegate does to decide "did the user change anything?". */
+  private static boolean delegateSeesChange(TransformMeta before, TransformMeta after)
+      throws Exception {
+    return !before.getXml().equals(after.getXml());
+  }
+
+  @Test
+  void editingConstantFieldsIsDetected() throws Exception {
+    TransformMeta transformMeta = constantTransform();
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    // What ConstantDialog.ok() does: take the live list, clear it, refill it from the grid.
+    List<ConstantField> fields = ((ConstantMeta) transformMeta.getTransform()).getFields();
+    fields.clear();
+    fields.add(new ConstantField("a", "String", "CHANGED BY THE USER"));
+
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+
+    System.out.println("---- BEFORE ----\n" + before.getXml());
+    System.out.println("---- AFTER ----\n" + after.getXml());
+    System.out.println(
+        "shared list instance: "
+            + (((ConstantMeta) before.getTransform()).getFields()
+                == ((ConstantMeta) after.getTransform()).getFields()));
+
+    assertEquals(true, delegateSeesChange(before, after), "the delegate must see the edit");
+  }
+}
diff --git a/plugins/transforms/creditcardvalidator/src/main/java/org/apache/hop/pipeline/transforms/creditcardvalidator/CreditCardValidatorMeta.java b/plugins/transforms/creditcardvalidator/src/main/java/org/apache/hop/pipeline/transforms/creditcardvalidator/CreditCardValidatorMeta.java
index ccaa24ac52..e0e81e84b9 100644
--- a/plugins/transforms/creditcardvalidator/src/main/java/org/apache/hop/pipeline/transforms/creditcardvalidator/CreditCardValidatorMeta.java
+++ b/plugins/transforms/creditcardvalidator/src/main/java/org/apache/hop/pipeline/transforms/creditcardvalidator/CreditCardValidatorMeta.java
@@ -69,19 +69,6 @@ public class CreditCardValidatorMeta
     super(); // allocate BaseTransformMeta
   }
 
-  public CreditCardValidatorMeta(CreditCardValidatorMeta m) {
-    this.fieldName = m.fieldName;
-    this.cardType = m.cardType;
-    this.notValidMessage = m.notValidMessage;
-    this.resultFieldName = m.resultFieldName;
-    this.onlyDigits = m.onlyDigits;
-  }
-
-  @Override
-  public CreditCardValidatorMeta clone() {
-    return new CreditCardValidatorMeta(this);
-  }
-
   @Override
   public void setDefault() {
     resultFieldName = "result";
diff --git a/plugins/transforms/cubeinput/src/main/java/org/apache/hop/pipeline/transforms/cubeinput/CubeInputMeta.java b/plugins/transforms/cubeinput/src/main/java/org/apache/hop/pipeline/transforms/cubeinput/CubeInputMeta.java
index f0e1816ed1..b2f8d964f0 100644
--- a/plugins/transforms/cubeinput/src/main/java/org/apache/hop/pipeline/transforms/cubeinput/CubeInputMeta.java
+++ b/plugins/transforms/cubeinput/src/main/java/org/apache/hop/pipeline/transforms/cubeinput/CubeInputMeta.java
@@ -68,18 +68,6 @@ public class CubeInputMeta extends BaseTransformMeta<CubeInput, CubeInputData> {
     file = new CubeFile();
   }
 
-  public CubeInputMeta(CubeInputMeta m) {
-    this();
-    this.file = new CubeFile(m.file);
-    this.rowLimit = m.rowLimit;
-    this.addFilenameResult = m.addFilenameResult;
-  }
-
-  @Override
-  public CubeInputMeta clone() {
-    return new CubeInputMeta(this);
-  }
-
   @Override
   public void setDefault() {
     this.file = new CubeFile();
diff --git a/plugins/transforms/cubeoutput/src/main/java/org/apache/hop/pipeline/transforms/cubeoutput/CubeOutputMeta.java b/plugins/transforms/cubeoutput/src/main/java/org/apache/hop/pipeline/transforms/cubeoutput/CubeOutputMeta.java
index 1f265793fd..c787d20783 100644
--- a/plugins/transforms/cubeoutput/src/main/java/org/apache/hop/pipeline/transforms/cubeoutput/CubeOutputMeta.java
+++ b/plugins/transforms/cubeoutput/src/main/java/org/apache/hop/pipeline/transforms/cubeoutput/CubeOutputMeta.java
@@ -67,18 +67,6 @@ public class CubeOutputMeta extends BaseTransformMeta<CubeOutput, CubeOutputData
     super(); // allocate BaseTransformMeta
   }
 
-  public CubeOutputMeta(CubeOutputMeta m) {
-    this.filename = m.filename;
-    this.filenameCreatingParentFolders = m.filenameCreatingParentFolders;
-    this.addToResultFilenames = m.addToResultFilenames;
-    this.doNotOpenNewFileInit = m.doNotOpenNewFileInit;
-  }
-
-  @Override
-  public CubeOutputMeta clone() {
-    return new CubeOutputMeta(this);
-  }
-
   @Override
   public void setDefault() {
     addToResultFilenames = false;
diff --git a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinMeta.java b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinMeta.java
index a8d9ce0902..e301335596 100644
--- a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinMeta.java
+++ b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinMeta.java
@@ -118,21 +118,6 @@ public class DatabaseJoinMeta extends BaseTransformMeta<DatabaseJoin, DatabaseJo
     super(); // allocate BaseTransformMeta
   }
 
-  public DatabaseJoinMeta(final DatabaseJoinMeta clone) {
-    super();
-
-    this.connection = clone.connection;
-    this.sql = clone.sql;
-    this.rowLimit = clone.rowLimit;
-    this.outerJoin = clone.outerJoin;
-    this.replaceVariables = clone.replaceVariables;
-    for (ParameterField field : clone.parameters) {
-      parameters.add(new ParameterField(field));
-    }
-    this.cached = clone.cached;
-    this.cacheSize = clone.cacheSize;
-  }
-
   public String getConnection() {
     return connection;
   }
@@ -229,11 +214,6 @@ public class DatabaseJoinMeta extends BaseTransformMeta<DatabaseJoin, DatabaseJo
     this.sql = sql;
   }
 
-  @Override
-  public Object clone() {
-    return new DatabaseJoinMeta(this);
-  }
-
   @Override
   public void setDefault() {
     rowLimit = 0;
diff --git a/plugins/transforms/databaselookup/src/main/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupMeta.java b/plugins/transforms/databaselookup/src/main/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupMeta.java
index d0ba4ee967..e6305af5ad 100644
--- a/plugins/transforms/databaselookup/src/main/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupMeta.java
+++ b/plugins/transforms/databaselookup/src/main/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupMeta.java
@@ -107,19 +107,6 @@ public class DatabaseLookupMeta extends BaseTransformMeta<DatabaseLookup, Databa
     lookup = new Lookup();
   }
 
-  public DatabaseLookupMeta(DatabaseLookupMeta m) {
-    this.connection = m.connection;
-    this.cached = m.cached;
-    this.cacheSize = m.cacheSize;
-    this.loadingAllDataInCache = m.loadingAllDataInCache;
-    this.lookup = new Lookup(m.lookup);
-  }
-
-  @Override
-  public DatabaseLookupMeta clone() {
-    return new DatabaseLookupMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/databaselookup/src/test/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupMetaTest.java b/plugins/transforms/databaselookup/src/test/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupMetaTest.java
index 5881268160..257f2a6ca6 100644
--- a/plugins/transforms/databaselookup/src/test/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupMetaTest.java
+++ b/plugins/transforms/databaselookup/src/test/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupMetaTest.java
@@ -268,7 +268,7 @@ class DatabaseLookupMetaTest {
     lookup.setFailingOnMultipleResults(true);
     lookup.setSchemaName("SCHEMA");
     lookup.setTableName("TABLE");
-    DatabaseLookupMeta meta2 = meta.clone();
+    DatabaseLookupMeta meta2 = (DatabaseLookupMeta) meta.clone();
     assertNotSame(meta2, meta);
     Lookup lookup2 = meta2.getLookup();
 
diff --git a/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridDialog.java b/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridDialog.java
index 8427f70ccc..50201dbcb3 100644
--- a/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridDialog.java
+++ b/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridDialog.java
@@ -73,7 +73,7 @@ public class DataGridDialog extends BaseTransformDialog {
     super(parent, variables, transformMeta, pipelineMeta);
     input = transformMeta;
 
-    dataGridMeta = input.clone();
+    dataGridMeta = (DataGridMeta) input.clone();
   }
 
   @Override
diff --git a/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridMeta.java b/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridMeta.java
index 57000b95f8..102ff6ce94 100644
--- a/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridMeta.java
+++ b/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridMeta.java
@@ -58,17 +58,6 @@ public class DataGridMeta extends BaseTransformMeta<DataGrid, DataGridData> {
     dataLines = new ArrayList<>();
   }
 
-  public DataGridMeta(DataGridMeta m) {
-    this();
-    this.dataGridFields = m.dataGridFields;
-    this.dataLines = m.dataLines;
-  }
-
-  @Override
-  public DataGridMeta clone() {
-    return new DataGridMeta(this);
-  }
-
   public List<DataGridDataMeta> getDataLines() {
     return dataLines;
   }
diff --git a/plugins/transforms/datagrid/src/test/java/org/apache/hop/pipeline/transforms/datagrid/DataGridChangeDetectionTest.java b/plugins/transforms/datagrid/src/test/java/org/apache/hop/pipeline/transforms/datagrid/DataGridChangeDetectionTest.java
new file mode 100644
index 0000000000..0754276c84
--- /dev/null
+++ b/plugins/transforms/datagrid/src/test/java/org/apache/hop/pipeline/transforms/datagrid/DataGridChangeDetectionTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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
+ *
+ *      http://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.hop.pipeline.transforms.datagrid;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Reproduces issue #8022 for the Data Grid transform, including the asymmetry reported in the
+ * comments: the "Data" tab is detected, the "Meta" tab is not.
+ *
+ * <p>DataGridMeta's copy constructor copies both list <i>references</i>, so a clone shares them
+ * with the live meta. DataGridDialog.getMetaInfo() mutates the shared field list in place
+ * (invisible to the delegate's before/after XML compare) while getDataInfo() assigns a brand new
+ * list (visible).
+ */
+class DataGridChangeDetectionTest {
+
+  @BeforeAll
+  static void setUpBeforeClass() throws Exception {
+    HopEnvironment.init();
+  }
+
+  private static TransformMeta dataGridTransform() {
+    DataGridMeta meta = new DataGridMeta();
+    DataGridFieldMeta field = new DataGridFieldMeta();
+    field.setName("a");
+    field.setType("String");
+    meta.getDataGridFields().add(field);
+
+    DataGridDataMeta line = new DataGridDataMeta();
+    line.getDatalines().add("row-1");
+    meta.getDataLines().add(line);
+
+    TransformMeta transformMeta = new TransformMeta("Data grid", meta);
+    transformMeta.setTransformPluginId("DataGrid");
+    return transformMeta;
+  }
+
+  private static boolean delegateSeesChange(TransformMeta before, TransformMeta after)
+      throws Exception {
+    return !before.getXml().equals(after.getXml());
+  }
+
+  @Test
+  void editingTheMetaTabIsNotDetected() throws Exception {
+    TransformMeta transformMeta = dataGridTransform();
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    // DataGridDialog.getMetaInfo(): clear + refill the *live* list.
+    DataGridMeta live = (DataGridMeta) transformMeta.getTransform();
+    live.getDataGridFields().clear();
+    DataGridFieldMeta renamed = new DataGridFieldMeta();
+    renamed.setName("RENAMED_BY_USER");
+    renamed.setType("String");
+    live.getDataGridFields().add(renamed);
+
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+
+    System.out.println(
+        "meta list shared with snapshot: "
+            + (((DataGridMeta) before.getTransform()).getDataGridFields()
+                == live.getDataGridFields()));
+    System.out.println("before snapshot already renamed: " + before.getXml().contains("RENAMED"));
+
+    assertTrue(delegateSeesChange(before, after), "renaming a Data Grid field must be detected");
+  }
+
+  @Test
+  void editingTheDataTabIsDetected() throws Exception {
+    TransformMeta transformMeta = dataGridTransform();
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    // DataGridDialog.getDataInfo(): build a new list and hand it over via the setter.
+    DataGridMeta live = (DataGridMeta) transformMeta.getTransform();
+    List<DataGridDataMeta> data = new ArrayList<>();
+    DataGridDataMeta line = new DataGridDataMeta();
+    line.getDatalines().add("EDITED_BY_USER");
+    data.add(line);
+    live.setDataLines(data);
+
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+
+    assertTrue(delegateSeesChange(before, after), "editing Data Grid data is detected today");
+    assertFalse(
+        before.getXml().contains("EDITED_BY_USER"),
+        "the setter replaced the list, so the snapshot kept the old rows");
+  }
+}
diff --git a/plugins/transforms/dbimpact/src/main/java/org/apache/hop/pipeline/transforms/dbimpact/input/DbImpactInputMeta.java b/plugins/transforms/dbimpact/src/main/java/org/apache/hop/pipeline/transforms/dbimpact/input/DbImpactInputMeta.java
index b97d076720..a82ebb9ca9 100644
--- a/plugins/transforms/dbimpact/src/main/java/org/apache/hop/pipeline/transforms/dbimpact/input/DbImpactInputMeta.java
+++ b/plugins/transforms/dbimpact/src/main/java/org/apache/hop/pipeline/transforms/dbimpact/input/DbImpactInputMeta.java
@@ -48,16 +48,6 @@ public class DbImpactInputMeta extends BaseTransformMeta<DbImpactInput, DbImpact
 
   public DbImpactInputMeta() {}
 
-  public DbImpactInputMeta(DbImpactInputMeta m) {
-    this();
-    this.fileNameField = m.fileNameField;
-  }
-
-  @Override
-  public DbImpactInputMeta clone() {
-    return new DbImpactInputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/dbproc/src/main/java/org/apache/hop/pipeline/transforms/dbproc/DBProcMeta.java b/plugins/transforms/dbproc/src/main/java/org/apache/hop/pipeline/transforms/dbproc/DBProcMeta.java
index 16a9ad122b..e0b6bff334 100644
--- a/plugins/transforms/dbproc/src/main/java/org/apache/hop/pipeline/transforms/dbproc/DBProcMeta.java
+++ b/plugins/transforms/dbproc/src/main/java/org/apache/hop/pipeline/transforms/dbproc/DBProcMeta.java
@@ -80,22 +80,6 @@ public class DBProcMeta extends BaseTransformMeta<DBProc, DBProcData> {
     this.result = new ProcResult();
   }
 
-  public DBProcMeta(DBProcMeta m) {
-    this();
-    this.connection = m.connection;
-    this.procedure = m.procedure;
-    for (ProcArgument argument : m.arguments) {
-      this.arguments.add(new ProcArgument(argument));
-    }
-    this.result = new ProcResult(m.result);
-    this.autoCommit = m.autoCommit;
-  }
-
-  @Override
-  public DBProcMeta clone() {
-    return new DBProcMeta(this);
-  }
-
   @Override
   public void setDefault() {
     connection = null;
diff --git a/plugins/transforms/delay/src/main/java/org/apache/hop/pipeline/transforms/delay/DelayMeta.java b/plugins/transforms/delay/src/main/java/org/apache/hop/pipeline/transforms/delay/DelayMeta.java
index 6a82bd6187..de6cdb4209 100644
--- a/plugins/transforms/delay/src/main/java/org/apache/hop/pipeline/transforms/delay/DelayMeta.java
+++ b/plugins/transforms/delay/src/main/java/org/apache/hop/pipeline/transforms/delay/DelayMeta.java
@@ -78,11 +78,6 @@ public class DelayMeta extends BaseTransformMeta<Delay, DelayData> {
     super(); // allocate BaseTransformMeta
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   public void setTimeoutField(String timeoutField) {
     this.timeoutField = Utils.isEmpty(timeoutField) ? null : timeoutField;
   }
diff --git a/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteMeta.java b/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteMeta.java
index 50f76297db..7199aec35f 100644
--- a/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteMeta.java
+++ b/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteMeta.java
@@ -121,11 +121,6 @@ public class DeleteMeta extends BaseTransformMeta<Delete, DeleteData> {
     this.lookup = new DeleteLookupField(obj.lookup);
   }
 
-  @Override
-  public Object clone() {
-    return new DeleteMeta(this);
-  }
-
   @Override
   public void setDefault() {
     commitSize = "100";
diff --git a/plugins/transforms/denormaliser/src/main/java/org/apache/hop/pipeline/transforms/denormaliser/DenormaliserMeta.java b/plugins/transforms/denormaliser/src/main/java/org/apache/hop/pipeline/transforms/denormaliser/DenormaliserMeta.java
index 26df4062d8..d4f8fc7ec8 100644
--- a/plugins/transforms/denormaliser/src/main/java/org/apache/hop/pipeline/transforms/denormaliser/DenormaliserMeta.java
+++ b/plugins/transforms/denormaliser/src/main/java/org/apache/hop/pipeline/transforms/denormaliser/DenormaliserMeta.java
@@ -69,22 +69,6 @@ public class DenormaliserMeta extends BaseTransformMeta<Denormaliser, Denormalis
     denormaliserTargetFields = new ArrayList<>();
   }
 
-  public DenormaliserMeta(DenormaliserMeta m) {
-    this();
-    this.keyField = m.keyField;
-    for (DenormaliserGroupField groupField : m.groupFields) {
-      this.groupFields.add(new DenormaliserGroupField(groupField));
-    }
-    for (DenormaliserTargetField targetField : m.denormaliserTargetFields) {
-      this.denormaliserTargetFields.add(new DenormaliserTargetField(targetField));
-    }
-  }
-
-  @Override
-  public DenormaliserMeta clone() {
-    return new DenormaliserMeta(this);
-  }
-
   /**
    * @return Returns the keyField.
    */
diff --git a/plugins/transforms/detectemptystream/src/main/java/org/apache/hop/pipeline/transforms/detectemptystream/DetectEmptyStreamMeta.java b/plugins/transforms/detectemptystream/src/main/java/org/apache/hop/pipeline/transforms/detectemptystream/DetectEmptyStreamMeta.java
index 4f589bde1f..4301394fe9 100644
--- a/plugins/transforms/detectemptystream/src/main/java/org/apache/hop/pipeline/transforms/detectemptystream/DetectEmptyStreamMeta.java
+++ b/plugins/transforms/detectemptystream/src/main/java/org/apache/hop/pipeline/transforms/detectemptystream/DetectEmptyStreamMeta.java
@@ -54,12 +54,6 @@ public class DetectEmptyStreamMeta
     readData(transformNode);
   }
 
-  @Override
-  public Object clone() {
-    Object retval = super.clone();
-    return retval;
-  }
-
   private void readData(Node transformNode) {
     // Do nothing
   }
diff --git a/plugins/transforms/detectlastrow/src/main/java/org/apache/hop/pipeline/transforms/detectlastrow/DetectLastRowMeta.java b/plugins/transforms/detectlastrow/src/main/java/org/apache/hop/pipeline/transforms/detectlastrow/DetectLastRowMeta.java
index e702597b30..961b1e9255 100644
--- a/plugins/transforms/detectlastrow/src/main/java/org/apache/hop/pipeline/transforms/detectlastrow/DetectLastRowMeta.java
+++ b/plugins/transforms/detectlastrow/src/main/java/org/apache/hop/pipeline/transforms/detectlastrow/DetectLastRowMeta.java
@@ -64,13 +64,6 @@ public class DetectLastRowMeta extends BaseTransformMeta<DetectLastRow, DetectLa
     this.resultFieldName = resultfieldname;
   }
 
-  @Override
-  public Object clone() {
-    DetectLastRowMeta retval = (DetectLastRowMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     resultFieldName = "result";
diff --git a/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupMeta.java b/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupMeta.java
index c789d0c8c5..0343cb4dba 100644
--- a/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupMeta.java
+++ b/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupMeta.java
@@ -209,33 +209,6 @@ public class DimensionLookupMeta extends BaseTransformMeta<DimensionLookup, Dime
     return true;
   }
 
-  @Override
-  public DimensionLookupMeta clone() {
-    return new DimensionLookupMeta(this);
-  }
-
-  public DimensionLookupMeta(DimensionLookupMeta m) {
-    this();
-    this.schemaName = m.schemaName;
-    this.tableName = m.tableName;
-    this.connection = m.connection;
-    this.update = m.update;
-    this.fields = new DLFields(m.fields);
-    this.sequenceName = m.sequenceName;
-    this.tkSourceField = m.tkSourceField;
-    this.commitSize = m.commitSize;
-    this.useBatchUpdate = m.useBatchUpdate;
-    this.minYear = m.minYear;
-    this.maxYear = m.maxYear;
-    this.cacheSize = m.cacheSize;
-    this.usingStartDateAlternative = m.usingStartDateAlternative;
-    this.startDateAlternative = m.startDateAlternative;
-    this.startDateFieldName = m.startDateFieldName;
-    this.preloadingCache = m.preloadingCache;
-    this.ignoreZeroLengthValidity = m.ignoreZeroLengthValidity;
-    this.unknownRowCheckDisabled = m.unknownRowCheckDisabled;
-  }
-
   @Override
   public void setDefault() {
     schemaName = "";
diff --git a/plugins/transforms/dynamicsqlrow/src/main/java/org/apache/hop/pipeline/transforms/dynamicsqlrow/DynamicSqlRowMeta.java b/plugins/transforms/dynamicsqlrow/src/main/java/org/apache/hop/pipeline/transforms/dynamicsqlrow/DynamicSqlRowMeta.java
index b9eea3da64..c6904577d0 100644
--- a/plugins/transforms/dynamicsqlrow/src/main/java/org/apache/hop/pipeline/transforms/dynamicsqlrow/DynamicSqlRowMeta.java
+++ b/plugins/transforms/dynamicsqlrow/src/main/java/org/apache/hop/pipeline/transforms/dynamicsqlrow/DynamicSqlRowMeta.java
@@ -119,11 +119,6 @@ public class DynamicSqlRowMeta extends BaseTransformMeta<DynamicSqlRow, DynamicS
     this.queryOnlyOnChange = meta.queryOnlyOnChange;
   }
 
-  @Override
-  public Object clone() {
-    return new DynamicSqlRowMeta(this);
-  }
-
   @Override
   public void setDefault() {
     this.connection = null;
diff --git a/plugins/transforms/edi2xml/src/main/java/org/apache/hop/pipeline/transforms/edi2xml/Edi2XmlMeta.java b/plugins/transforms/edi2xml/src/main/java/org/apache/hop/pipeline/transforms/edi2xml/Edi2XmlMeta.java
index 7372b6481c..34a3be63b6 100644
--- a/plugins/transforms/edi2xml/src/main/java/org/apache/hop/pipeline/transforms/edi2xml/Edi2XmlMeta.java
+++ b/plugins/transforms/edi2xml/src/main/java/org/apache/hop/pipeline/transforms/edi2xml/Edi2XmlMeta.java
@@ -57,17 +57,6 @@ public class Edi2XmlMeta extends BaseTransformMeta<Edi2Xml, Edi2XmlData> {
     inputField = "";
   }
 
-  public Edi2XmlMeta(Edi2XmlMeta m) {
-    this();
-    this.outputField = m.outputField;
-    this.inputField = m.inputField;
-  }
-
-  @Override
-  public Edi2XmlMeta clone() {
-    return new Edi2XmlMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta r,
diff --git a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputMeta.java b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputMeta.java
index 5f27625f2d..4482f86f5b 100644
--- a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputMeta.java
+++ b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputMeta.java
@@ -315,52 +315,6 @@ public class ExcelInputMeta extends BaseTransformMeta<ExcelInput, ExcelInputData
     this.sheets = new ArrayList<>();
   }
 
-  public ExcelInputMeta(ExcelInputMeta m) {
-    this();
-    m.fields.forEach(f -> this.fields.add(new ExcelInputField(f)));
-    m.sheets.forEach(s -> this.sheets.add(new EISheet(s)));
-    m.files.forEach(f -> this.files.add(new EIFile(f)));
-    this.fileField = m.fileField;
-    this.sheetField = m.sheetField;
-    this.startsWithHeader = m.startsWithHeader;
-    this.schemaDefinition = m.schemaDefinition;
-    this.ignoreFields = m.ignoreFields;
-    this.stopOnEmpty = m.stopOnEmpty;
-    this.ignoreEmptyRows = m.ignoreEmptyRows;
-    this.rowNumberField = m.rowNumberField;
-    this.sheetRowNumberField = m.sheetRowNumberField;
-    this.rowLimit = m.rowLimit;
-    this.strictTypes = m.strictTypes;
-    this.errorIgnored = m.errorIgnored;
-    this.errorLineSkipped = m.errorLineSkipped;
-    this.warningFilesDestinationDirectory = m.warningFilesDestinationDirectory;
-    this.warningFilesExtension = m.warningFilesExtension;
-    this.errorFilesDestinationDirectory = m.errorFilesDestinationDirectory;
-    this.errorFilesExtension = m.errorFilesExtension;
-    this.lineNumberFilesDestinationDirectory = m.lineNumberFilesDestinationDirectory;
-    this.lineNumberFilesExtension = m.lineNumberFilesExtension;
-    this.acceptingFilenames = m.acceptingFilenames;
-    this.acceptingField = m.acceptingField;
-    this.acceptingTransformName = m.acceptingTransformName;
-    this.encoding = m.encoding;
-    this.addFilenamesToResult = m.addFilenamesToResult;
-    this.shortFileFieldName = m.shortFileFieldName;
-    this.pathFieldName = m.pathFieldName;
-    this.hiddenFieldName = m.hiddenFieldName;
-    this.lastModificationTimeFieldName = m.lastModificationTimeFieldName;
-    this.uriNameFieldName = m.uriNameFieldName;
-    this.rootUriNameFieldName = m.rootUriNameFieldName;
-    this.extensionFieldName = m.extensionFieldName;
-    this.sizeFieldName = m.sizeFieldName;
-    this.spreadSheetType = m.spreadSheetType;
-    this.password = m.password;
-  }
-
-  @Override
-  public ExcelInputMeta clone() {
-    return new ExcelInputMeta(this);
-  }
-
   @Override
   public void setDefault() {
     startsWithHeader = true;
diff --git a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformMeta.java b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformMeta.java
index 0b5828e742..48b48ca1c2 100644
--- a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformMeta.java
+++ b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformMeta.java
@@ -154,11 +154,6 @@ public class ExcelWriterTransformMeta
     this.appendEmpty = Math.max(appendEmpty, 0);
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   @Override
   public void setDefault() {
 
diff --git a/plugins/transforms/excel/src/test/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputMetaTest.java b/plugins/transforms/excel/src/test/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputMetaTest.java
index 123e31ae00..b8b86a5c14 100644
--- a/plugins/transforms/excel/src/test/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputMetaTest.java
+++ b/plugins/transforms/excel/src/test/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputMetaTest.java
@@ -59,7 +59,7 @@ class ExcelInputMetaTest {
         TransformSerializationTestUtil.testSerialization(
             "/excel-input-transform.xml", ExcelInputMeta.class);
 
-    ExcelInputMeta clone = meta.clone();
+    ExcelInputMeta clone = (ExcelInputMeta) meta.clone();
 
     assertEquals(meta.getFiles().size(), clone.getFiles().size());
   }
diff --git a/plugins/transforms/execinfo/src/main/java/org/apache/hop/pipeline/transforms/execinfo/ExecInfoMeta.java b/plugins/transforms/execinfo/src/main/java/org/apache/hop/pipeline/transforms/execinfo/ExecInfoMeta.java
index bb6ee1237c..0b1ef09090 100644
--- a/plugins/transforms/execinfo/src/main/java/org/apache/hop/pipeline/transforms/execinfo/ExecInfoMeta.java
+++ b/plugins/transforms/execinfo/src/main/java/org/apache/hop/pipeline/transforms/execinfo/ExecInfoMeta.java
@@ -67,22 +67,6 @@ public class ExecInfoMeta extends BaseTransformMeta<ExecInfo, ExecInfoData> {
     super(); // allocate BaseTransformMeta
   }
 
-  public ExecInfoMeta(ExecInfoMeta m) {
-    this.location = m.location;
-    this.operationType = m.operationType;
-    this.idFieldName = m.idFieldName;
-    this.parentIdFieldName = m.parentIdFieldName;
-    this.typeFieldName = m.typeFieldName;
-    this.nameFieldName = m.nameFieldName;
-    this.includeChildrenFieldName = m.includeChildrenFieldName;
-    this.limitFieldName = m.limitFieldName;
-  }
-
-  @Override
-  public ExecInfoMeta clone() {
-    return new ExecInfoMeta(this);
-  }
-
   @Override
   public void setDefault() {
     operationType = OperationType.GetExecutionIds;
diff --git a/plugins/transforms/execprocess/src/main/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessMeta.java b/plugins/transforms/execprocess/src/main/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessMeta.java
index fee366876f..6a3ec9720a 100644
--- a/plugins/transforms/execprocess/src/main/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessMeta.java
+++ b/plugins/transforms/execprocess/src/main/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessMeta.java
@@ -99,11 +99,6 @@ public class ExecProcessMeta extends BaseTransformMeta<ExecProcess, ExecProcessD
     m.argumentFields.forEach(f -> this.argumentFields.add(new EPField(f)));
   }
 
-  @Override
-  public ExecProcessMeta clone() {
-    return new ExecProcessMeta(this);
-  }
-
   @Override
   public void setDefault() {
     resultFieldName = "Result output";
diff --git a/plugins/transforms/execprocess/src/test/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessMetaTest.java b/plugins/transforms/execprocess/src/test/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessMetaTest.java
index 1496833daf..e9ae862c8a 100644
--- a/plugins/transforms/execprocess/src/test/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessMetaTest.java
+++ b/plugins/transforms/execprocess/src/test/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessMetaTest.java
@@ -131,7 +131,7 @@ class ExecProcessMetaTest {
     a.getArgumentFields().add(f);
     a.setOutputLineDelimiter("|");
 
-    ExecProcessMeta b = a.clone();
+    ExecProcessMeta b = (ExecProcessMeta) a.clone();
     assertNotSame(a, b);
     assertNotSame(a.getArgumentFields(), b.getArgumentFields());
     assertNotSame(a.getArgumentFields().get(0), b.getArgumentFields().get(0));
diff --git a/plugins/transforms/execsqlrow/src/main/java/org/apache/hop/pipeline/transforms/execsqlrow/ExecSqlRowMeta.java b/plugins/transforms/execsqlrow/src/main/java/org/apache/hop/pipeline/transforms/execsqlrow/ExecSqlRowMeta.java
index 526fab72cf..d1ad10eea7 100644
--- a/plugins/transforms/execsqlrow/src/main/java/org/apache/hop/pipeline/transforms/execsqlrow/ExecSqlRowMeta.java
+++ b/plugins/transforms/execsqlrow/src/main/java/org/apache/hop/pipeline/transforms/execsqlrow/ExecSqlRowMeta.java
@@ -242,11 +242,6 @@ public class ExecSqlRowMeta extends BaseTransformMeta<ExecSqlRow, ExecSqlRowData
     this.updateField = updateField;
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   @Override
   public void setDefault() {
     sqlFromfile = false;
diff --git a/plugins/transforms/fake/src/main/java/org/apache/hop/pipeline/transforms/fake/FakeMeta.java b/plugins/transforms/fake/src/main/java/org/apache/hop/pipeline/transforms/fake/FakeMeta.java
index 7873173f06..dd0f6bb3ad 100644
--- a/plugins/transforms/fake/src/main/java/org/apache/hop/pipeline/transforms/fake/FakeMeta.java
+++ b/plugins/transforms/fake/src/main/java/org/apache/hop/pipeline/transforms/fake/FakeMeta.java
@@ -54,17 +54,6 @@ public class FakeMeta extends BaseTransformMeta<Fake, FakeData> {
     this.fields = new ArrayList<>();
   }
 
-  @Override
-  public FakeMeta clone() {
-    FakeMeta copy = (FakeMeta) super.clone();
-    copy.locale = locale;
-    copy.fields = new ArrayList<>();
-    for (FakeField field : fields) {
-      copy.fields.add(new FakeField(field));
-    }
-    return copy;
-  }
-
   @Override
   public void setDefault() {
     locale = "en";
diff --git a/plugins/transforms/fake/src/test/java/org/apache/hop/pipeline/transforms/fake/FakeMetaTest.java b/plugins/transforms/fake/src/test/java/org/apache/hop/pipeline/transforms/fake/FakeMetaTest.java
index 636984fe15..cd9afdbd49 100644
--- a/plugins/transforms/fake/src/test/java/org/apache/hop/pipeline/transforms/fake/FakeMetaTest.java
+++ b/plugins/transforms/fake/src/test/java/org/apache/hop/pipeline/transforms/fake/FakeMetaTest.java
@@ -68,7 +68,7 @@ class FakeMetaTest {
     args.add(new FakeArgument("int", "18"));
     meta.getFields().add(new FakeField("age", "number", "numberBetween", args));
 
-    FakeMeta clone = meta.clone();
+    FakeMeta clone = (FakeMeta) meta.clone();
     assertEquals("fr", clone.getLocale());
     assertEquals(1, clone.getFields().size());
 
diff --git a/plugins/transforms/fieldschangesequence/src/main/java/org/apache/hop/pipeline/transforms/fieldschangesequence/FieldsChangeSequenceMeta.java b/plugins/transforms/fieldschangesequence/src/main/java/org/apache/hop/pipeline/transforms/fieldschangesequence/FieldsChangeSequenceMeta.java
index 7a446c6fd0..a96f1f31b9 100644
--- a/plugins/transforms/fieldschangesequence/src/main/java/org/apache/hop/pipeline/transforms/fieldschangesequence/FieldsChangeSequenceMeta.java
+++ b/plugins/transforms/fieldschangesequence/src/main/java/org/apache/hop/pipeline/transforms/fieldschangesequence/FieldsChangeSequenceMeta.java
@@ -76,18 +76,6 @@ public class FieldsChangeSequenceMeta
     fields = new ArrayList<>();
   }
 
-  public FieldsChangeSequenceMeta(FieldsChangeSequenceMeta meta) {
-    super();
-
-    this.start = meta.getStart();
-    this.increment = meta.getIncrement();
-    this.resultFieldName = meta.getResultFieldName();
-    this.fields = new ArrayList<>();
-    for (FieldsChangeSequenceField field : meta.getFields()) {
-      fields.add(new FieldsChangeSequenceField(field.getName()));
-    }
-  }
-
   public String getStart() {
     return start;
   }
@@ -106,11 +94,6 @@ public class FieldsChangeSequenceMeta
     this.resultFieldName = resultfieldName;
   }
 
-  @Override
-  public Object clone() {
-    return new FieldsChangeSequenceMeta(this);
-  }
-
   /**
    * @return Returns the fieldName.
    */
diff --git a/plugins/transforms/fieldsplitter/src/main/java/org/apache/hop/pipeline/transforms/fieldsplitter/FieldSplitterMeta.java b/plugins/transforms/fieldsplitter/src/main/java/org/apache/hop/pipeline/transforms/fieldsplitter/FieldSplitterMeta.java
index e7da47e15b..6cbe7c1dae 100644
--- a/plugins/transforms/fieldsplitter/src/main/java/org/apache/hop/pipeline/transforms/fieldsplitter/FieldSplitterMeta.java
+++ b/plugins/transforms/fieldsplitter/src/main/java/org/apache/hop/pipeline/transforms/fieldsplitter/FieldSplitterMeta.java
@@ -100,21 +100,6 @@ public class FieldSplitterMeta extends BaseTransformMeta<FieldSplitter, FieldSpl
     fields = new ArrayList<>();
   }
 
-  public FieldSplitterMeta(FieldSplitterMeta m) {
-    this();
-    this.splitField = m.splitField;
-    this.delimiter = m.delimiter;
-    this.enclosure = m.enclosure;
-    this.escapeString = m.escapeString;
-    this.keepSplitField = m.keepSplitField;
-    m.fields.forEach(f -> this.fields.add(new FSField(f)));
-  }
-
-  @Override
-  public FieldSplitterMeta clone() {
-    return new FieldSplitterMeta(this);
-  }
-
   @Override
   public void setDefault() {
     splitField = "";
diff --git a/plugins/transforms/fileexists/src/main/java/org/apache/hop/pipeline/transforms/fileexists/FileExistsMeta.java b/plugins/transforms/fileexists/src/main/java/org/apache/hop/pipeline/transforms/fileexists/FileExistsMeta.java
index 47f8fb91c6..af3769c0c9 100644
--- a/plugins/transforms/fileexists/src/main/java/org/apache/hop/pipeline/transforms/fileexists/FileExistsMeta.java
+++ b/plugins/transforms/fileexists/src/main/java/org/apache/hop/pipeline/transforms/fileexists/FileExistsMeta.java
@@ -136,12 +136,6 @@ public class FileExistsMeta extends BaseTransformMeta<FileExists, FileExistsData
     this.includefiletype = includefiletype;
   }
 
-  @Override
-  public Object clone() {
-    FileExistsMeta retval = (FileExistsMeta) super.clone();
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     resultfieldname = "result";
diff --git a/plugins/transforms/filelocked/src/main/java/org/apache/hop/pipeline/transforms/filelocked/FileLockedMeta.java b/plugins/transforms/filelocked/src/main/java/org/apache/hop/pipeline/transforms/filelocked/FileLockedMeta.java
index 7a8422fc76..085096d8cd 100644
--- a/plugins/transforms/filelocked/src/main/java/org/apache/hop/pipeline/transforms/filelocked/FileLockedMeta.java
+++ b/plugins/transforms/filelocked/src/main/java/org/apache/hop/pipeline/transforms/filelocked/FileLockedMeta.java
@@ -103,13 +103,6 @@ public class FileLockedMeta extends BaseTransformMeta<FileLocked, FileLockedData
     this.addresultfilenames = addresultfilenames;
   }
 
-  @Override
-  public Object clone() {
-    FileLockedMeta retval = (FileLockedMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     resultfieldname = "result";
diff --git a/plugins/transforms/filemetadata/src/main/java/org/apache/hop/pipeline/transforms/filemetadata/FileMetadataMeta.java b/plugins/transforms/filemetadata/src/main/java/org/apache/hop/pipeline/transforms/filemetadata/FileMetadataMeta.java
index ac11190d02..d39117cb2b 100644
--- a/plugins/transforms/filemetadata/src/main/java/org/apache/hop/pipeline/transforms/filemetadata/FileMetadataMeta.java
+++ b/plugins/transforms/filemetadata/src/main/java/org/apache/hop/pipeline/transforms/filemetadata/FileMetadataMeta.java
@@ -71,15 +71,6 @@ public class FileMetadataMeta extends BaseTransformMeta<FileMetadata, FileMetada
     this.enclosureCandidates = new ArrayList<>();
   }
 
-  public FileMetadataMeta(FileMetadataMeta m) {
-    this();
-    this.fileName = m.fileName;
-    this.limitRows = m.limitRows;
-    this.defaultCharset = m.defaultCharset;
-    m.delimiterCandidates.forEach(c -> this.delimiterCandidates.add(new FMCandidate(c)));
-    m.enclosureCandidates.forEach(c -> this.enclosureCandidates.add(new FMCandidate(c)));
-  }
-
   /**
    * This method is called every time a new transform is created and should allocate/set the
    * transform configuration to sensible defaults. The values set here will be used by Spoon when a
@@ -102,18 +93,6 @@ public class FileMetadataMeta extends BaseTransformMeta<FileMetadata, FileMetada
     enclosureCandidates.add(new FMCandidate("'"));
   }
 
-  /**
-   * This method is used when a transform is duplicated. It needs to return a deep copy of this
-   * object. Be sure to create proper deep copies if the transform configuration is stored in
-   * modifiable objects.
-   *
-   * @return a deep copy of this
-   */
-  @Override
-  public FileMetadataMeta clone() {
-    return new FileMetadataMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/filesfromresult/src/main/java/org/apache/hop/pipeline/transforms/filesfromresult/FilesFromResultMeta.java b/plugins/transforms/filesfromresult/src/main/java/org/apache/hop/pipeline/transforms/filesfromresult/FilesFromResultMeta.java
index c54fe5e210..33335237c5 100644
--- a/plugins/transforms/filesfromresult/src/main/java/org/apache/hop/pipeline/transforms/filesfromresult/FilesFromResultMeta.java
+++ b/plugins/transforms/filesfromresult/src/main/java/org/apache/hop/pipeline/transforms/filesfromresult/FilesFromResultMeta.java
@@ -57,12 +57,6 @@ public class FilesFromResultMeta extends BaseTransformMeta<FilesFromResult, File
     readData(transformNode);
   }
 
-  @Override
-  public Object clone() {
-    Object retval = super.clone();
-    return retval;
-  }
-
   private void readData(Node transformNode) {
     // Do nothing
   }
diff --git a/plugins/transforms/filestoresult/src/main/java/org/apache/hop/pipeline/transforms/filestoresult/FilesToResultMeta.java b/plugins/transforms/filestoresult/src/main/java/org/apache/hop/pipeline/transforms/filestoresult/FilesToResultMeta.java
index 44cfc3cbdb..34eb1cae48 100644
--- a/plugins/transforms/filestoresult/src/main/java/org/apache/hop/pipeline/transforms/filestoresult/FilesToResultMeta.java
+++ b/plugins/transforms/filestoresult/src/main/java/org/apache/hop/pipeline/transforms/filestoresult/FilesToResultMeta.java
@@ -54,16 +54,6 @@ public class FilesToResultMeta extends BaseTransformMeta<FilesToResult, FilesToR
     fileType = FileType.GENERAL;
   }
 
-  public FilesToResultMeta(FilesToResultMeta m) {
-    this.filenameField = m.filenameField;
-    this.fileType = m.fileType;
-  }
-
-  @Override
-  public FilesToResultMeta clone() {
-    return new FilesToResultMeta(this);
-  }
-
   @Override
   public void setDefault() {
     filenameField = null;
diff --git a/plugins/transforms/flattener/src/main/java/org/apache/hop/pipeline/transforms/flattener/FlattenerMeta.java b/plugins/transforms/flattener/src/main/java/org/apache/hop/pipeline/transforms/flattener/FlattenerMeta.java
index cecabb55b8..cb866dc071 100644
--- a/plugins/transforms/flattener/src/main/java/org/apache/hop/pipeline/transforms/flattener/FlattenerMeta.java
+++ b/plugins/transforms/flattener/src/main/java/org/apache/hop/pipeline/transforms/flattener/FlattenerMeta.java
@@ -59,17 +59,6 @@ public class FlattenerMeta extends BaseTransformMeta<Flattener, FlattenerData> {
     this.targetFields = new ArrayList<>();
   }
 
-  public FlattenerMeta(FlattenerMeta m) {
-    this();
-    this.fieldName = m.fieldName;
-    m.targetFields.forEach(f -> this.targetFields.add(new FField(f)));
-  }
-
-  @Override
-  public FlattenerMeta clone() {
-    return new FlattenerMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaMeta.java b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaMeta.java
index 5129c6ac1d..e0e3497bb8 100644
--- a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaMeta.java
+++ b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaMeta.java
@@ -65,11 +65,6 @@ public class FormulaMeta extends BaseTransformMeta<Formula, FormulaData> {
     }
   }
 
-  @Override
-  public FormulaMeta clone() {
-    return new FormulaMeta(this);
-  }
-
   @Override
   public boolean supportsErrorHandling() {
     // Rows for which a formula can not be calculated can be diverted instead of stopping the
diff --git a/plugins/transforms/formula/src/test/java/org/apache/hop/pipeline/transforms/formula/FormulaMetaTest.java b/plugins/transforms/formula/src/test/java/org/apache/hop/pipeline/transforms/formula/FormulaMetaTest.java
index 0578758480..99ab649743 100644
--- a/plugins/transforms/formula/src/test/java/org/apache/hop/pipeline/transforms/formula/FormulaMetaTest.java
+++ b/plugins/transforms/formula/src/test/java/org/apache/hop/pipeline/transforms/formula/FormulaMetaTest.java
@@ -67,7 +67,7 @@ class FormulaMetaTest {
     // This is what the transform dialog does when snapshotting the "before" state: the snapshot
     // must survive the dialog clearing and repopulating the live list, otherwise the change goes
     // unnoticed and the pipeline can't be saved.
-    FormulaMeta before = formulaMeta.clone();
+    FormulaMeta before = (FormulaMeta) formulaMeta.clone();
 
     formulaMeta.getFormulas().clear();
     formulaMeta.getFormulas().add(new FormulaMetaFunction("test", "2+2", 1, 10, 2, "", false));
diff --git a/plugins/transforms/fuzzymatch/src/main/java/org/apache/hop/pipeline/transforms/fuzzymatch/FuzzyMatchMeta.java b/plugins/transforms/fuzzymatch/src/main/java/org/apache/hop/pipeline/transforms/fuzzymatch/FuzzyMatchMeta.java
index 4bd759ff27..54dd157f7a 100644
--- a/plugins/transforms/fuzzymatch/src/main/java/org/apache/hop/pipeline/transforms/fuzzymatch/FuzzyMatchMeta.java
+++ b/plugins/transforms/fuzzymatch/src/main/java/org/apache/hop/pipeline/transforms/fuzzymatch/FuzzyMatchMeta.java
@@ -147,27 +147,6 @@ public class FuzzyMatchMeta extends BaseTransformMeta<FuzzyMatch, FuzzyMatchData
     this.maxMatches = String.valueOf(DEFAULT_MAX_MATCHES);
   }
 
-  public FuzzyMatchMeta(FuzzyMatchMeta m) {
-    this();
-    this.algorithm = m.algorithm;
-    this.lookupField = m.lookupField;
-    this.mainStreamField = m.mainStreamField;
-    this.outputMatchField = m.outputMatchField;
-    this.outputValueField = m.outputValueField;
-    this.caseSensitive = m.caseSensitive;
-    this.minimalValue = m.minimalValue;
-    this.maximalValue = m.maximalValue;
-    this.separator = m.separator;
-    setMatchMode(m.getMatchMode());
-    this.maxMatches = m.maxMatches;
-    m.lookupValues.forEach(v -> this.lookupValues.add(new FMLookupValue(v)));
-  }
-
-  @Override
-  public FuzzyMatchMeta clone() {
-    return new FuzzyMatchMeta(this);
-  }
-
   @Override
   public void setDefault() {
     algorithm = NONE;
diff --git a/plugins/transforms/fuzzymatch/src/test/java/org/apache/hop/pipeline/transforms/fuzzymatch/FuzzyMatchMetaTest.java b/plugins/transforms/fuzzymatch/src/test/java/org/apache/hop/pipeline/transforms/fuzzymatch/FuzzyMatchMetaTest.java
index ce68284156..85d6c4635f 100644
--- a/plugins/transforms/fuzzymatch/src/test/java/org/apache/hop/pipeline/transforms/fuzzymatch/FuzzyMatchMetaTest.java
+++ b/plugins/transforms/fuzzymatch/src/test/java/org/apache/hop/pipeline/transforms/fuzzymatch/FuzzyMatchMetaTest.java
@@ -93,7 +93,7 @@ class FuzzyMatchMetaTest {
     meta.setLookupField("lookup");
     meta.setLookupValues(List.of(new FuzzyMatchMeta.FMLookupValue("id", "rid")));
 
-    FuzzyMatchMeta copy = meta.clone();
+    FuzzyMatchMeta copy = (FuzzyMatchMeta) meta.clone();
 
     assertNotSame(meta, copy);
     assertEquals(FuzzyMatchMeta.MatchMode.ALL_ROWS, copy.getMatchMode());
diff --git a/plugins/transforms/getfilenames/src/main/java/org/apache/hop/pipeline/transforms/getfilenames/GetFileNamesMeta.java b/plugins/transforms/getfilenames/src/main/java/org/apache/hop/pipeline/transforms/getfilenames/GetFileNamesMeta.java
index 4136559128..b4d204c3e4 100644
--- a/plugins/transforms/getfilenames/src/main/java/org/apache/hop/pipeline/transforms/getfilenames/GetFileNamesMeta.java
+++ b/plugins/transforms/getfilenames/src/main/java/org/apache/hop/pipeline/transforms/getfilenames/GetFileNamesMeta.java
@@ -171,11 +171,6 @@ public class GetFileNamesMeta extends BaseTransformMeta<GetFileNames, GetFileNam
     }
   }
 
-  @Override
-  public Object clone() {
-    return (GetFileNamesMeta) super.clone();
-  }
-
   @Override
   public void setDefault() {
     doNotFailIfNoFile = false;
diff --git a/plugins/transforms/getfilesrowcount/src/main/java/org/apache/hop/pipeline/transforms/getfilesrowcount/GetFilesRowsCountMeta.java b/plugins/transforms/getfilesrowcount/src/main/java/org/apache/hop/pipeline/transforms/getfilesrowcount/GetFilesRowsCountMeta.java
index 6e776da5ba..0398f9e48c 100644
--- a/plugins/transforms/getfilesrowcount/src/main/java/org/apache/hop/pipeline/transforms/getfilesrowcount/GetFilesRowsCountMeta.java
+++ b/plugins/transforms/getfilesrowcount/src/main/java/org/apache/hop/pipeline/transforms/getfilesrowcount/GetFilesRowsCountMeta.java
@@ -104,25 +104,6 @@ public class GetFilesRowsCountMeta
     this.files = new ArrayList<>();
   }
 
-  public GetFilesRowsCountMeta(GetFilesRowsCountMeta m) {
-    this();
-    this.includeFilesCount = m.includeFilesCount;
-    this.filesCountFieldName = m.filesCountFieldName;
-    this.rowsCountFieldName = m.rowsCountFieldName;
-    this.rowSeparatorFormat = m.rowSeparatorFormat;
-    this.rowSeparator = m.rowSeparator;
-    this.fileFromField = m.fileFromField;
-    this.addResultFilename = m.addResultFilename;
-    this.outputFilenameField = m.outputFilenameField;
-    this.smartCount = m.smartCount;
-    m.files.forEach(f -> this.files.add(new GCFile(f)));
-  }
-
-  @Override
-  public GetFilesRowsCountMeta clone() {
-    return new GetFilesRowsCountMeta(this);
-  }
-
   @Override
   public void setDefault() {
     smartCount = false;
diff --git a/plugins/transforms/getsubfolders/src/main/java/org/apache/hop/pipeline/transforms/getsubfolders/GetSubFoldersMeta.java b/plugins/transforms/getsubfolders/src/main/java/org/apache/hop/pipeline/transforms/getsubfolders/GetSubFoldersMeta.java
index 17d6a10f89..31b3e2b0d8 100644
--- a/plugins/transforms/getsubfolders/src/main/java/org/apache/hop/pipeline/transforms/getsubfolders/GetSubFoldersMeta.java
+++ b/plugins/transforms/getsubfolders/src/main/java/org/apache/hop/pipeline/transforms/getsubfolders/GetSubFoldersMeta.java
@@ -88,22 +88,6 @@ public class GetSubFoldersMeta extends BaseTransformMeta<GetSubFolders, GetSubFo
     files = new ArrayList<>();
   }
 
-  public GetSubFoldersMeta(GetSubFoldersMeta m) {
-    this();
-    this.includeRowNumber = m.includeRowNumber;
-    this.rowNumberField = m.rowNumberField;
-    this.dynamicFolderNameField = m.dynamicFolderNameField;
-    this.folderNameDynamic = m.folderNameDynamic;
-    this.rowLimit = m.rowLimit;
-    this.childrenFieldName = m.childrenFieldName;
-    m.files.forEach(f -> this.files.add(new GSFile(f)));
-  }
-
-  @Override
-  public GetSubFoldersMeta clone() {
-    return new GetSubFoldersMeta(this);
-  }
-
   @Override
   public void setDefault() {
     folderNameDynamic = false;
diff --git a/plugins/transforms/gettablenames/src/main/java/org/apache/hop/pipeline/transforms/gettablenames/GetTableNamesMeta.java b/plugins/transforms/gettablenames/src/main/java/org/apache/hop/pipeline/transforms/gettablenames/GetTableNamesMeta.java
index 38c70fd618..62a9a77b74 100644
--- a/plugins/transforms/gettablenames/src/main/java/org/apache/hop/pipeline/transforms/gettablenames/GetTableNamesMeta.java
+++ b/plugins/transforms/gettablenames/src/main/java/org/apache/hop/pipeline/transforms/gettablenames/GetTableNamesMeta.java
@@ -147,30 +147,6 @@ public class GetTableNamesMeta extends BaseTransformMeta<GetTableNames, GetTable
     super();
   }
 
-  public GetTableNamesMeta(GetTableNamesMeta m) {
-    this();
-    this.connection = m.connection;
-    this.schemaName = m.schemaName;
-    this.tableNameFieldName = m.tableNameFieldName;
-    this.sqlCreationFieldName = m.sqlCreationFieldName;
-    this.objectTypeFieldName = m.objectTypeFieldName;
-    this.isSystemObjectFieldName = m.isSystemObjectFieldName;
-    this.includeCatalog = m.includeCatalog;
-    this.includeSchema = m.includeSchema;
-    this.includeTable = m.includeTable;
-    this.includeView = m.includeView;
-    this.includeProcedure = m.includeProcedure;
-    this.includeSynonym = m.includeSynonym;
-    this.addSchemaInOutput = m.addSchemaInOutput;
-    this.dynamicSchema = m.dynamicSchema;
-    this.schemaNameField = m.schemaNameField;
-  }
-
-  @Override
-  public GetTableNamesMeta clone() {
-    return new GetTableNamesMeta(this);
-  }
-
   @Override
   public void setDefault() {
     connection = null;
diff --git a/plugins/transforms/getvariable/src/main/java/org/apache/hop/pipeline/transforms/getvariable/GetVariableMeta.java b/plugins/transforms/getvariable/src/main/java/org/apache/hop/pipeline/transforms/getvariable/GetVariableMeta.java
index f222d694d2..658380e029 100644
--- a/plugins/transforms/getvariable/src/main/java/org/apache/hop/pipeline/transforms/getvariable/GetVariableMeta.java
+++ b/plugins/transforms/getvariable/src/main/java/org/apache/hop/pipeline/transforms/getvariable/GetVariableMeta.java
@@ -59,16 +59,6 @@ public class GetVariableMeta extends BaseTransformMeta<GetVariable, GetVariableD
     this.fieldDefinitions = new ArrayList<>();
   }
 
-  public GetVariableMeta(GetVariableMeta m) {
-    this();
-    m.fieldDefinitions.forEach(f -> this.fieldDefinitions.add(new FieldDefinition(f)));
-  }
-
-  @Override
-  public GetVariableMeta clone() {
-    return new GetVariableMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByMeta.java b/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByMeta.java
index 1360b542cb..c337443325 100644
--- a/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByMeta.java
+++ b/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByMeta.java
@@ -181,25 +181,6 @@ public class GroupByMeta extends BaseTransformMeta<GroupBy, GroupByData> {
     this.passAllRows = passAllRows;
   }
 
-  @Override
-  public GroupByMeta clone() {
-    GroupByMeta groupByMeta = (GroupByMeta) super.clone();
-
-    List<GroupingField> groupingFieldsCopy = new ArrayList<>();
-    for (GroupingField item : groupingFields) {
-      groupingFieldsCopy.add(item.clone());
-    }
-    groupByMeta.setGroupingFields(groupingFieldsCopy);
-
-    List<Aggregation> aggsCopy = new ArrayList<>();
-    for (Aggregation aggregation : aggregations) {
-      aggsCopy.add(aggregation.clone());
-    }
-    groupByMeta.setAggregations(aggsCopy);
-
-    return groupByMeta;
-  }
-
   @Override
   public void setDefault() {
     directory = "${java.io.tmpdir}";
diff --git a/plugins/transforms/groupby/src/test/java/org/apache/hop/pipeline/transforms/GroupByMetaTest.java b/plugins/transforms/groupby/src/test/java/org/apache/hop/pipeline/transforms/GroupByMetaTest.java
index d1b21f70e0..5c7ef9c666 100644
--- a/plugins/transforms/groupby/src/test/java/org/apache/hop/pipeline/transforms/GroupByMetaTest.java
+++ b/plugins/transforms/groupby/src/test/java/org/apache/hop/pipeline/transforms/GroupByMetaTest.java
@@ -34,7 +34,7 @@ class GroupByMetaTest {
   @Test
   void testClone() throws Exception {
     GroupByMeta meta1 = generateTestMeta();
-    GroupByMeta meta2 = meta1.clone();
+    GroupByMeta meta2 = (GroupByMeta) meta1.clone();
 
     compareMetas(meta1, meta2);
   }
diff --git a/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpMeta.java b/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpMeta.java
index 47f5bdb08f..d06069f0a7 100644
--- a/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpMeta.java
+++ b/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpMeta.java
@@ -164,29 +164,6 @@ public class HttpMeta extends BaseTransformMeta<Http, HttpData> {
     this.encoding = Const.UTF_8;
   }
 
-  public HttpMeta(HttpMeta m) {
-    this();
-    this.closeIdleConnectionsTime = m.closeIdleConnectionsTime;
-    this.connectionTimeout = m.connectionTimeout;
-    this.encoding = m.encoding;
-    this.httpLogin = m.httpLogin;
-    this.httpPassword = m.httpPassword;
-    this.ignoreSsl = m.ignoreSsl;
-    this.proxyHost = m.proxyHost;
-    this.proxyPort = m.proxyPort;
-    this.socketTimeout = m.socketTimeout;
-    this.url = m.url;
-    this.urlField = m.urlField;
-    this.urlInField = m.urlInField;
-    this.lookupParameters = new LookupParameters(m.lookupParameters);
-    this.resultFields = new ResultFields(m.resultFields);
-  }
-
-  @Override
-  public Object clone() {
-    return new HttpMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMeta.java b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMeta.java
index 090451ae0a..e6168bfea8 100644
--- a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMeta.java
+++ b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMeta.java
@@ -127,13 +127,6 @@ public class HttpPostMeta extends BaseTransformMeta<HttpPost, HttpPostData> {
     super(); // allocate BaseTransformMeta
   }
 
-  @Override
-  public Object clone() {
-    HttpPostMeta retval = (HttpPostMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     encoding = Const.UTF_8;
diff --git a/plugins/transforms/ifnull/src/main/java/org/apache/hop/pipeline/transforms/ifnull/IfNullMeta.java b/plugins/transforms/ifnull/src/main/java/org/apache/hop/pipeline/transforms/ifnull/IfNullMeta.java
index 79ca841193..e822cffa5e 100644
--- a/plugins/transforms/ifnull/src/main/java/org/apache/hop/pipeline/transforms/ifnull/IfNullMeta.java
+++ b/plugins/transforms/ifnull/src/main/java/org/apache/hop/pipeline/transforms/ifnull/IfNullMeta.java
@@ -95,22 +95,6 @@ public class IfNullMeta extends BaseTransformMeta<IfNull, IfNullData> {
     this.fields = new ArrayList<>();
   }
 
-  public IfNullMeta(final IfNullMeta meta) {
-    this();
-    this.selectFields = meta.selectFields;
-    this.selectValuesType = meta.selectValuesType;
-    this.replaceAllByValue = meta.replaceAllByValue;
-    this.replaceAllMask = meta.replaceAllMask;
-    this.setEmptyStringAll = meta.setEmptyStringAll;
-
-    for (Field field : meta.fields) {
-      this.fields.add(new Field(field));
-    }
-    for (ValueType vt : meta.valueTypes) {
-      this.valueTypes.add(new ValueType(vt));
-    }
-  }
-
   /**
    * @return Returns the setEmptyStringAll.
    */
@@ -125,11 +109,6 @@ public class IfNullMeta extends BaseTransformMeta<IfNull, IfNullData> {
     this.setEmptyStringAll = setEmptyStringAll;
   }
 
-  @Override
-  public Object clone() {
-    return new IfNullMeta(this);
-  }
-
   public boolean isSelectFields() {
     return selectFields;
   }
diff --git a/plugins/transforms/insertupdate/src/main/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateMeta.java b/plugins/transforms/insertupdate/src/main/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateMeta.java
index 9e13748019..0dc928948e 100644
--- a/plugins/transforms/insertupdate/src/main/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateMeta.java
+++ b/plugins/transforms/insertupdate/src/main/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateMeta.java
@@ -128,13 +128,6 @@ public class InsertUpdateMeta extends BaseTransformMeta<InsertUpdate, InsertUpda
     this.commitSize = commitSize;
   }
 
-  @Override
-  public Object clone() {
-    InsertUpdateMeta retval = (InsertUpdateMeta) super.clone();
-
-    return retval;
-  }
-
   /**
    * Returns the table name.
    *
diff --git a/plugins/transforms/insertupdate/src/test/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateChangeDetectionTest.java b/plugins/transforms/insertupdate/src/test/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateChangeDetectionTest.java
new file mode 100644
index 0000000000..29ce039649
--- /dev/null
+++ b/plugins/transforms/insertupdate/src/test/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateChangeDetectionTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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
+ *
+ *      http://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.hop.pipeline.transforms.insertupdate;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Reproduces issue #8022 for Insert/Update. InsertUpdateMeta.clone() is a shallow Object.clone(),
+ * so the nested InsertUpdateLookupField - which owns the schema, the table and both grids - is
+ * shared with the "before" snapshot the delegate compares against. Only the three properties that
+ * live directly on InsertUpdateMeta (connection, commit size, "do not perform any updates") survive
+ * the shallow copy as independent values, which is exactly the split the reporter describes.
+ */
+class InsertUpdateChangeDetectionTest {
+
+  @BeforeAll
+  static void setUpBeforeClass() throws Exception {
+    HopEnvironment.init();
+  }
+
+  private static TransformMeta insertUpdateTransform() {
+    InsertUpdateMeta meta = new InsertUpdateMeta();
+    meta.setConnection("db");
+    meta.setCommitSize("100");
+    meta.getInsertUpdateLookupField().setSchemaName("public");
+    meta.getInsertUpdateLookupField().setTableName("customers");
+    meta.getInsertUpdateLookupField().getLookupKeys().add(new InsertUpdateKeyField());
+
+    TransformMeta transformMeta = new TransformMeta("Insert / Update", meta);
+    transformMeta.setTransformPluginId("InsertUpdate");
+    return transformMeta;
+  }
+
+  private static boolean delegateSeesChange(TransformMeta before, TransformMeta after)
+      throws Exception {
+    return !before.getXml().equals(after.getXml());
+  }
+
+  @Test
+  void changingTheTargetTableIsNotDetected() throws Exception {
+    TransformMeta transformMeta = insertUpdateTransform();
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    // InsertUpdateDialog.getInfo(): setters on the *shared* nested lookup object.
+    InsertUpdateMeta live = (InsertUpdateMeta) transformMeta.getTransform();
+    live.getInsertUpdateLookupField().setSchemaName("reporting");
+    live.getInsertUpdateLookupField().setTableName("orders");
+    live.getInsertUpdateLookupField().getLookupKeys().clear();
+
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+
+    System.out.println(
+        "nested lookup object shared with snapshot: "
+            + (((InsertUpdateMeta) before.getTransform()).getInsertUpdateLookupField()
+                == live.getInsertUpdateLookupField()));
+    System.out.println(
+        "before snapshot already says 'orders': " + before.getXml().contains("orders"));
+
+    assertTrue(delegateSeesChange(before, after), "changing schema/table/keys must be detected");
+  }
+
+  @Test
+  void changingTheCommitSizeIsDetected() throws Exception {
+    TransformMeta transformMeta = insertUpdateTransform();
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    // A property that lives directly on InsertUpdateMeta, so the shallow copy holds its own value.
+    ((InsertUpdateMeta) transformMeta.getTransform()).setCommitSize("5000");
+
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+
+    assertTrue(delegateSeesChange(before, after), "commit size is detected today");
+  }
+}
diff --git a/plugins/transforms/insertupdate/src/test/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateUndoTest.java b/plugins/transforms/insertupdate/src/test/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateUndoTest.java
new file mode 100644
index 0000000000..514886281a
--- /dev/null
+++ b/plugins/transforms/insertupdate/src/test/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateUndoTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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
+ *
+ *      http://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.hop.pipeline.transforms.insertupdate;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The shallow clone behind issue #8022 also corrupts undo. HopGuiPipelineTransformDelegate stores
+ * the same aliased "before" snapshot as the undo entry, and HopGuiPipelineUndoDelegate restores it
+ * with replaceMeta(). Anything that lives behind the aliased reference was never captured, so undo
+ * rolls back the top-level properties and silently keeps the edited ones.
+ */
+class InsertUpdateUndoTest {
+
+  @BeforeAll
+  static void setUpBeforeClass() throws Exception {
+    HopEnvironment.init();
+  }
+
+  @Test
+  void undoRestoresTheWholeTransform() throws Exception {
+    InsertUpdateMeta meta = new InsertUpdateMeta();
+    meta.setConnection("db");
+    meta.setCommitSize("100");
+    meta.getInsertUpdateLookupField().setSchemaName("public");
+    meta.getInsertUpdateLookupField().setTableName("customers");
+
+    TransformMeta transformMeta = new TransformMeta("Insert / Update", meta);
+    transformMeta.setTransformPluginId("InsertUpdate");
+
+    // The delegate's snapshot, which also becomes the undo entry's "previous" state.
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    // The user edits both a top-level property and the target table in one dialog session.
+    InsertUpdateMeta live = (InsertUpdateMeta) transformMeta.getTransform();
+    live.setCommitSize("5000");
+    live.getInsertUpdateLookupField().setTableName("orders");
+
+    // The XML diff sees the commit size, so the edit *is* detected and an undo entry is recorded.
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+    org.junit.jupiter.api.Assertions.assertNotEquals(
+        before.getXml(), after.getXml(), "precondition: this edit is detected");
+
+    // HopGuiPipelineUndoDelegate, case ChangeTransform.
+    transformMeta.replaceMeta((TransformMeta) before.clone());
+
+    InsertUpdateMeta restored = (InsertUpdateMeta) transformMeta.getTransform();
+    System.out.println("commit size after undo: " + restored.getCommitSize());
+    System.out.println(
+        "table name  after undo: " + restored.getInsertUpdateLookupField().getTableName());
+
+    assertEquals("100", restored.getCommitSize(), "commit size is rolled back");
+    assertEquals(
+        "customers",
+        restored.getInsertUpdateLookupField().getTableName(),
+        "the target table must be rolled back too");
+  }
+}
diff --git a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMeta.java b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMeta.java
index dc6d5dbc55..2dfa9e6b38 100644
--- a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMeta.java
+++ b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMeta.java
@@ -79,12 +79,6 @@ public class JaninoMeta extends BaseTransformMeta<Janino, JaninoData> {
     this.functions = new ArrayList<>();
   }
 
-  public JaninoMeta(JaninoMeta m) {
-    this();
-    m.functions.forEach(f -> this.functions.add(new JaninoMetaFunction(f)));
-    this.javaTargetVersion = m.javaTargetVersion;
-  }
-
   /**
    * Resolved Janino compiler source/target version (major Java version number), for backwards
    * compatibility when pipelines omit {@link #javaTargetVersion} or contain invalid values.
@@ -97,11 +91,6 @@ public class JaninoMeta extends BaseTransformMeta<Janino, JaninoData> {
     return javaTargetVersion;
   }
 
-  @Override
-  public Object clone() {
-    return new JaninoMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/javafilter/JavaFilterMeta.java b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/javafilter/JavaFilterMeta.java
index 9c1cc356e1..f68c441b3c 100644
--- a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/javafilter/JavaFilterMeta.java
+++ b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/javafilter/JavaFilterMeta.java
@@ -99,12 +99,6 @@ public class JavaFilterMeta extends BaseTransformMeta<JavaFilter, JavaFilterData
     return Objects.hash(getTransformIOMeta().getTargetStreams(), condition);
   }
 
-  @Override
-  public Object clone() {
-    JavaFilterMeta retval = (JavaFilterMeta) super.clone();
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     condition = "true";
diff --git a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassMeta.java b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassMeta.java
index ab5e299fe9..dd5574acf1 100644
--- a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassMeta.java
+++ b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassMeta.java
@@ -220,20 +220,6 @@ public class UserDefinedJavaClassMeta
     usageParameters = new ArrayList<>();
   }
 
-  public UserDefinedJavaClassMeta(UserDefinedJavaClassMeta m) {
-    this();
-    this.cookedTransformClass = null;
-    this.clearingResultFields = m.clearingResultFields;
-    m.fields.forEach(f -> this.fields.add(new FieldInfo(f)));
-    m.definitions.forEach(d -> this.definitions.add(new UserDefinedJavaClassDef(d)));
-    m.infoTransformDefinitions.forEach(
-        d -> this.infoTransformDefinitions.add(new InfoTransformDefinition(d)));
-    m.targetTransformDefinitions.forEach(
-        d -> this.targetTransformDefinitions.add(new TargetTransformDefinition(d)));
-    m.usageParameters.forEach(u -> this.usageParameters.add(new UsageParameter(u)));
-    this.javaTargetVersion = m.javaTargetVersion;
-  }
-
   @VisibleForTesting
   Class<?> cookClass(UserDefinedJavaClassDef def, ClassLoader clsLoader)
       throws CompileException, IOException, HopTransformException {
@@ -387,11 +373,6 @@ public class UserDefinedJavaClassMeta
     hasChanged = true;
   }
 
-  @Override
-  public UserDefinedJavaClassMeta clone() {
-    return new UserDefinedJavaClassMeta(this);
-  }
-
   private boolean checkClassCooked(ILogChannel logChannel) {
     boolean ok = cookedTransformClass != null && cookErrors.isEmpty();
     if (hasChanged) {
diff --git a/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassMetaTest.java b/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassMetaTest.java
index ba9f738957..b35cdf335d 100644
--- a/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassMetaTest.java
+++ b/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassMetaTest.java
@@ -366,7 +366,7 @@ class UserDefinedJavaClassMetaTest {
   void clone_copiesJavaTargetVersion() {
     UserDefinedJavaClassMeta original = new UserDefinedJavaClassMeta();
     original.setJavaTargetVersion(17);
-    UserDefinedJavaClassMeta copy = original.clone();
+    UserDefinedJavaClassMeta copy = (UserDefinedJavaClassMeta) original.clone();
 
     assertNotSame(original, copy);
     assertEquals(17, copy.getJavaTargetVersion());
diff --git a/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesMeta.java b/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesMeta.java
index 6d61b03a9b..af8f916e69 100644
--- a/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesMeta.java
+++ b/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesMeta.java
@@ -163,24 +163,6 @@ public class ScriptValuesMeta extends BaseTransformMeta<ScriptValues, ScriptValu
     jsScripts.add(script);
   }
 
-  public ScriptValuesMeta(ScriptValuesMeta m) {
-    // Deliberately not calling this(): the no-arg constructor seeds a default "Script 1" for new
-    // transforms, and copying on top of that would add one more phantom script on every clone.
-    //
-    super();
-    jsScripts = new ArrayList<>();
-    scriptFields = new ArrayList<>();
-    this.optimizationLevel = m.optimizationLevel;
-    this.languageVersion = m.languageVersion;
-    m.jsScripts.forEach(s -> this.jsScripts.add(new ScriptValuesScript(s)));
-    m.scriptFields.forEach(f -> scriptFields.add(new ScriptField(f)));
-  }
-
-  @Override
-  public Object clone() {
-    return new ScriptValuesMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/jdbc-metadata/src/main/java/org/apache/hop/pipeline/transforms/jdbcmetadata/JdbcMetadataMeta.java b/plugins/transforms/jdbc-metadata/src/main/java/org/apache/hop/pipeline/transforms/jdbcmetadata/JdbcMetadataMeta.java
index b112c95de8..7254b3d817 100644
--- a/plugins/transforms/jdbc-metadata/src/main/java/org/apache/hop/pipeline/transforms/jdbcmetadata/JdbcMetadataMeta.java
+++ b/plugins/transforms/jdbc-metadata/src/main/java/org/apache/hop/pipeline/transforms/jdbcmetadata/JdbcMetadataMeta.java
@@ -569,22 +569,6 @@ public class JdbcMetadataMeta extends BaseTransformMeta<JdbcMetadata, JdbcMetada
     this.outputFields = outputFields;
   }
 
-  /**
-   * This method is used when a step is duplicated in Spoon. It needs to return a deep copy of this
-   * step meta object. Be sure to create proper deep copies if the step configuration is stored in
-   * modifiable objects.
-   *
-   * <p>See org.pentaho.di.trans.steps.rowgenerator.RowGeneratorMeta.clone() for an example on
-   * creating a deep copy.
-   *
-   * @return a deep copy of this
-   */
-  @Override
-  public Object clone() {
-    Object retval = super.clone();
-    return retval;
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsoninput/JsonInputMeta.java b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsoninput/JsonInputMeta.java
index e94a14bec4..495c5db90f 100644
--- a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsoninput/JsonInputMeta.java
+++ b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsoninput/JsonInputMeta.java
@@ -220,34 +220,6 @@ public class JsonInputMeta extends BaseFileInputMeta<JsonInput, JsonInputData, B
     valueField = "";
   }
 
-  public JsonInputMeta(JsonInputMeta m) {
-    this();
-    this.addResultFile = m.addResultFile;
-    this.defaultPathLeafToNull = m.defaultPathLeafToNull;
-    this.doNotFailIfNoFile = m.doNotFailIfNoFile;
-    this.filenameField = m.filenameField;
-    this.ignoringMissingPath = m.ignoringMissingPath;
-    this.includeFilename = m.includeFilename;
-    this.includeRowNumber = m.includeRowNumber;
-    this.inFields = m.inFields;
-    this.sourceAFile = m.sourceAFile;
-    this.ignoringEmptyFile = m.ignoringEmptyFile;
-    this.readUrl = m.readUrl;
-    this.removeSourceField = m.removeSourceField;
-    this.rowLimit = m.rowLimit;
-    this.rowNumberField = m.rowNumberField;
-    this.valueField = m.valueField;
-    this.additionalOutputFields = new BaseFileInputAdditionalFields(m.additionalOutputFields);
-    this.fileInput = new BaseFileInput(m.fileInput);
-    m.inputFields.forEach(f -> inputFields.add(new JsonInputField(f)));
-    syncFieldSourceFlags();
-  }
-
-  @Override
-  public JsonInputMeta clone() {
-    return new JsonInputMeta(this);
-  }
-
   /**
    * @return Returns the shortFileFieldName.
    */
diff --git a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonnormalize/JsonNormalizeInputMeta.java b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonnormalize/JsonNormalizeInputMeta.java
index bc99846f7a..28728411f6 100644
--- a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonnormalize/JsonNormalizeInputMeta.java
+++ b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonnormalize/JsonNormalizeInputMeta.java
@@ -240,38 +240,6 @@ public class JsonNormalizeInputMeta
     ignoreMissingField = true;
   }
 
-  public JsonNormalizeInputMeta(JsonNormalizeInputMeta m) {
-    this();
-    this.addResultFile = m.addResultFile;
-    this.doNotFailIfNoFile = m.doNotFailIfNoFile;
-    this.filenameField = m.filenameField;
-    this.includeFilename = m.includeFilename;
-    this.includeRowNumber = m.includeRowNumber;
-    this.inFields = m.inFields;
-    this.sourceAFile = m.sourceAFile;
-    this.ignoringEmptyFile = m.ignoringEmptyFile;
-    this.readUrl = m.readUrl;
-    this.removeSourceField = m.removeSourceField;
-    this.rowLimit = m.rowLimit;
-    this.rowNumberField = m.rowNumberField;
-    this.valueField = m.valueField;
-    this.recordPath = m.recordPath;
-    this.fieldSeparator = m.fieldSeparator;
-    this.maxFlattenDepth = m.maxFlattenDepth;
-    this.arrayHandling = m.arrayHandling;
-    this.beyondDepthBehavior = m.beyondDepthBehavior;
-    this.ignoreMissingField = m.ignoreMissingField;
-    this.additionalOutputFields = new BaseFileInputAdditionalFields(m.additionalOutputFields);
-    this.fileInput = new BaseFileInput(m.fileInput);
-    m.inputFields.forEach(f -> inputFields.add(new JsonInputField(f)));
-    syncFieldSourceFlags();
-  }
-
-  @Override
-  public JsonNormalizeInputMeta clone() {
-    return new JsonNormalizeInputMeta(this);
-  }
-
   public String getShortFileNameField() {
     return additionalOutputFields.getShortFilenameField();
   }
diff --git a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputMeta.java b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputMeta.java
index 0ec8de550f..4085be7bf3 100644
--- a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputMeta.java
+++ b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputMeta.java
@@ -132,25 +132,6 @@ public class JsonOutputMeta extends BaseFileOutputMeta<JsonOutput, JsonOutputDat
     doNotOpenNewFileInit = true;
   }
 
-  public JsonOutputMeta(JsonOutputMeta m) {
-    this();
-    this.addToResult = m.addToResult;
-    this.createParentFolder = m.createParentFolder;
-    this.doNotOpenNewFileInit = m.doNotOpenNewFileInit;
-    this.encoding = m.encoding;
-    this.fileAppended = m.fileAppended;
-    this.jsonBloc = m.jsonBloc;
-    this.nrRowsInBloc = m.nrRowsInBloc;
-    this.operationType = m.operationType;
-    this.outputValue = m.outputValue;
-    m.outputFields.forEach(f -> outputFields.add(new JsonOutputField(f)));
-  }
-
-  @Override
-  public Object clone() {
-    return new JsonOutputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutputenhanced/JsonEOutputMeta.java b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutputenhanced/JsonEOutputMeta.java
index 5a1004407e..bff6217327 100644
--- a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutputenhanced/JsonEOutputMeta.java
+++ b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutputenhanced/JsonEOutputMeta.java
@@ -184,27 +184,6 @@ public class JsonEOutputMeta extends BaseTransformMeta<JsonEOutput, JsonEOutputD
     jsonBloc = "";
   }
 
-  public JsonEOutputMeta(JsonEOutputMeta m) {
-    this();
-    this.addingToResult = m.addingToResult;
-    this.encoding = m.encoding;
-    this.jsonBloc = m.jsonBloc;
-    this.jsonPrettified = m.jsonPrettified;
-    this.jsonSizeFieldName = m.jsonSizeFieldName;
-    this.operationType = m.operationType;
-    this.outputValue = m.outputValue;
-    this.useArrayWithSingleInstance = m.useArrayWithSingleInstance;
-    this.useSingleItemPerGroup = m.useSingleItemPerGroup;
-    this.fileSettings = new FileSettings(m.fileSettings);
-    m.keyFields.forEach(f -> this.keyFields.add(new JsonEOutputKeyField(f)));
-    m.outputFields.forEach(f -> this.outputFields.add(new JsonEOutputField(f)));
-  }
-
-  @Override
-  public Object clone() {
-    return new JsonEOutputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/kafka/src/main/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputDialog.java b/plugins/transforms/kafka/src/main/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputDialog.java
index b662f6d2e8..0ef5d7b818 100644
--- a/plugins/transforms/kafka/src/main/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputDialog.java
+++ b/plugins/transforms/kafka/src/main/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputDialog.java
@@ -996,7 +996,7 @@ public class KafkaConsumerInputDialog extends BaseTransformDialog {
   }
 
   private PipelineMeta loadKafkaPipelineMeta() throws HopException {
-    KafkaConsumerInputMeta copyMeta = meta.clone();
+    KafkaConsumerInputMeta copyMeta = (KafkaConsumerInputMeta) meta.clone();
     updateMeta(copyMeta);
     return TransformWithMappingMeta.loadMappingMeta(copyMeta, getMetadataProvider(), variables);
   }
diff --git a/plugins/transforms/kafka/src/main/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputMeta.java b/plugins/transforms/kafka/src/main/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputMeta.java
index bc84cbd7c2..7993138305 100644
--- a/plugins/transforms/kafka/src/main/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputMeta.java
+++ b/plugins/transforms/kafka/src/main/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputMeta.java
@@ -244,31 +244,6 @@ public class KafkaConsumerInputMeta
     headersField = new HeadersConsumerField("");
   }
 
-  public KafkaConsumerInputMeta(KafkaConsumerInputMeta m) {
-    super(m);
-    this.keyField = new KeyConsumerField(m.keyField);
-    this.messageField = new MessageConsumerField(m.messageField);
-    this.topicField = new TopicConsumerField(m.topicField);
-    this.offsetField = new OffsetConsumerField(m.offsetField);
-    this.partitionField = new PartitionConsumerField(m.partitionField);
-    this.timestampField = new TimestampConsumerField(m.timestampField);
-    this.filename = m.filename;
-    this.executionInformationLocation = m.executionInformationLocation;
-    this.executionDataProfile = m.executionDataProfile;
-    this.batchSize = m.batchSize;
-    this.batchDuration = m.batchDuration;
-    this.subTransform = m.subTransform;
-    this.directBootstrapServers = m.directBootstrapServers;
-    this.topics = new ArrayList<>(m.topics);
-    this.consumerGroup = m.consumerGroup;
-    this.autoCommit = m.autoCommit;
-    this.stopWhenIdle = m.stopWhenIdle;
-    this.maxIdleTimeMs = m.maxIdleTimeMs;
-    this.mappingMetaRetriever = m.mappingMetaRetriever;
-    this.options = new ArrayList<>();
-    m.options.forEach(o -> this.options.add(new KafkaOption(o)));
-  }
-
   public RowMeta getRowMeta(String origin, IVariables variables) throws HopTransformException {
     RowMeta rowMeta = new RowMeta();
     putFieldOnRowMeta(getKeyField(), rowMeta, origin, variables);
@@ -312,11 +287,6 @@ public class KafkaConsumerInputMeta
             getHeadersField()));
   }
 
-  @Override
-  public KafkaConsumerInputMeta clone() {
-    return new KafkaConsumerInputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/kafka/src/test/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputMetaTest.java b/plugins/transforms/kafka/src/test/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputMetaTest.java
index 7dd6596728..4d66927e54 100644
--- a/plugins/transforms/kafka/src/test/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputMetaTest.java
+++ b/plugins/transforms/kafka/src/test/java/org/apache/hop/pipeline/transforms/kafka/consumer/KafkaConsumerInputMetaTest.java
@@ -249,7 +249,7 @@ class KafkaConsumerInputMetaTest {
     meta.setStopWhenIdle(true);
     meta.setMaxIdleTimeMs("2500");
 
-    KafkaConsumerInputMeta copy = meta.clone();
+    KafkaConsumerInputMeta copy = (KafkaConsumerInputMeta) meta.clone();
     assertTrue(copy.isStopWhenIdle());
     assertEquals("2500", copy.getMaxIdleTimeMs());
   }
diff --git a/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapinput/LdapInputMeta.java b/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapinput/LdapInputMeta.java
index 72c9828bb7..66bfb4e18f 100644
--- a/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapinput/LdapInputMeta.java
+++ b/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapinput/LdapInputMeta.java
@@ -348,14 +348,7 @@ public class LdapInputMeta extends BaseTransformMeta<LdapInput, LdapInputData>
   @Override
   public Object clone() {
     LdapInputMeta retval = (LdapInputMeta) super.clone();
-    if (inputFields != null) {
-      retval.inputFields = new ArrayList<>();
-      for (LdapInputField field : inputFields) {
-        if (field != null) {
-          retval.inputFields.add((LdapInputField) field.clone());
-        }
-      }
-    } else {
+    if (retval.inputFields == null) {
       retval.inputFields = new ArrayList<>();
     }
     return retval;
diff --git a/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapoutput/LdapOutputMeta.java b/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapoutput/LdapOutputMeta.java
index bc3a771cb0..b1dc71f8bd 100644
--- a/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapoutput/LdapOutputMeta.java
+++ b/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapoutput/LdapOutputMeta.java
@@ -502,14 +502,7 @@ public class LdapOutputMeta extends BaseTransformMeta<LdapOutput, LdapOutputData
   @Override
   public Object clone() {
     LdapOutputMeta retval = (LdapOutputMeta) super.clone();
-    if (fields != null) {
-      retval.fields = new ArrayList<>();
-      for (LdapOutputField field : fields) {
-        retval.fields.add(
-            new LdapOutputField(
-                field.getUpdateLookup(), field.getUpdateStream(), field.isUpdate()));
-      }
-    } else {
+    if (retval.fields == null) {
       retval.fields = new ArrayList<>();
     }
     return retval;
diff --git a/plugins/transforms/loadfileinput/src/main/java/org/apache/hop/pipeline/transforms/loadfileinput/LoadFileInputMeta.java b/plugins/transforms/loadfileinput/src/main/java/org/apache/hop/pipeline/transforms/loadfileinput/LoadFileInputMeta.java
index 42a8dc1cfc..9897031a2a 100644
--- a/plugins/transforms/loadfileinput/src/main/java/org/apache/hop/pipeline/transforms/loadfileinput/LoadFileInputMeta.java
+++ b/plugins/transforms/loadfileinput/src/main/java/org/apache/hop/pipeline/transforms/loadfileinput/LoadFileInputMeta.java
@@ -181,29 +181,6 @@ public class LoadFileInputMeta extends BaseTransformMeta<LoadFileInput, LoadFile
     dynamicFilenameField = null;
   }
 
-  public LoadFileInputMeta(LoadFileInputMeta m) {
-    this();
-    this.addingResultFile = m.addingResultFile;
-    this.dynamicFilenameField = m.dynamicFilenameField;
-    this.encoding = m.encoding;
-    this.fileInField = m.fileInField;
-    this.filenameField = m.filenameField;
-    this.ignoreEmptyFile = m.ignoreEmptyFile;
-    this.ignoreMissingPath = m.ignoreMissingPath;
-    this.includeFilename = m.includeFilename;
-    this.includeRowNumber = m.includeRowNumber;
-    this.rowLimit = m.rowLimit;
-    this.rowNumberField = m.rowNumberField;
-    this.additionalFields = new BaseFileInputAdditionalFields(m.additionalFields);
-    m.inputFields.forEach(field -> this.inputFields.add(new LoadFileInputField(field)));
-    m.inputFiles.forEach(file -> this.inputFiles.add(new InputFile(file)));
-  }
-
-  @Override
-  public Object clone() {
-    return new LoadFileInputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta r,
diff --git a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/input/MappingInputMeta.java b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/input/MappingInputMeta.java
index 3e84466a53..79e35f1bb1 100644
--- a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/input/MappingInputMeta.java
+++ b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/input/MappingInputMeta.java
@@ -60,18 +60,6 @@ public class MappingInputMeta extends BaseTransformMeta<MappingInput, MappingInp
     this.fields = new ArrayList<>();
   }
 
-  public MappingInputMeta(MappingInputMeta m) {
-    this();
-    for (InputField field : m.fields) {
-      fields.add(new InputField(field));
-    }
-  }
-
-  @Override
-  public MappingInputMeta clone() {
-    return new MappingInputMeta(this);
-  }
-
   @Override
   public void setDefault() {
     // Do nothing
diff --git a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/mapping/SimpleMappingMeta.java b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/mapping/SimpleMappingMeta.java
index d7ba513fed..0b35b9644f 100644
--- a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/mapping/SimpleMappingMeta.java
+++ b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/mapping/SimpleMappingMeta.java
@@ -76,17 +76,6 @@ public class SimpleMappingMeta extends TransformWithMappingMeta<SimpleMapping, S
     ioMappings = new IOMappings();
   }
 
-  public SimpleMappingMeta(SimpleMappingMeta m) {
-    super(m);
-    this.runConfigurationName = m.runConfigurationName;
-    this.ioMappings = new IOMappings(m.ioMappings);
-  }
-
-  @Override
-  public SimpleMappingMeta clone() {
-    return new SimpleMappingMeta(this);
-  }
-
   @Override
   public void setDefault() {
     MappingIODefinition inputDefinition = new MappingIODefinition(null, null);
diff --git a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/multimapping/MultiMappingMeta.java b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/multimapping/MultiMappingMeta.java
index a2b921f584..e915cd0396 100644
--- a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/multimapping/MultiMappingMeta.java
+++ b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/multimapping/MultiMappingMeta.java
@@ -107,18 +107,6 @@ public class MultiMappingMeta extends TransformWithMappingMeta<MultiMapping, Mul
     ioMappings = new MultiIOMappings();
   }
 
-  public MultiMappingMeta(MultiMappingMeta m) {
-    super(m);
-    this.runConfigurationName = m.runConfigurationName;
-    this.ioMappings =
-        m.ioMappings != null ? new MultiIOMappings(m.ioMappings) : new MultiIOMappings();
-  }
-
-  @Override
-  public MultiMappingMeta clone() {
-    return new MultiMappingMeta(this);
-  }
-
   @Override
   public void setDefault() {
     MultiMappingInputDefinition inputDefinition = new MultiMappingInputDefinition(null, null);
diff --git a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/output/MappingOutputMeta.java b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/output/MappingOutputMeta.java
index bc39074459..67a68646ed 100644
--- a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/output/MappingOutputMeta.java
+++ b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/output/MappingOutputMeta.java
@@ -45,15 +45,6 @@ public class MappingOutputMeta extends BaseTransformMeta<MappingOutput, MappingO
     super();
   }
 
-  public MappingOutputMeta(MappingOutputMeta m) {
-    this();
-  }
-
-  @Override
-  public MappingOutputMeta clone() {
-    return new MappingOutputMeta(this);
-  }
-
   @Override
   public void setDefault() {
     // Do nothing
diff --git a/plugins/transforms/mapping/src/test/java/org/apache/hop/pipeline/transforms/input/MappingInputMetaTest.java b/plugins/transforms/mapping/src/test/java/org/apache/hop/pipeline/transforms/input/MappingInputMetaTest.java
index 91217356dd..b7916b35d9 100644
--- a/plugins/transforms/mapping/src/test/java/org/apache/hop/pipeline/transforms/input/MappingInputMetaTest.java
+++ b/plugins/transforms/mapping/src/test/java/org/apache/hop/pipeline/transforms/input/MappingInputMetaTest.java
@@ -46,7 +46,7 @@ class MappingInputMetaTest {
 
     meta.setChanged();
 
-    MappingInputMeta copy = meta.clone();
+    MappingInputMeta copy = (MappingInputMeta) meta.clone();
 
     assertEquals(meta.getFields().size(), copy.getFields().size());
     for (int i = 0; i < meta.getFields().size(); i++) {
diff --git a/plugins/transforms/mapping/src/test/java/org/apache/hop/pipeline/transforms/multimapping/MultiMappingMetaTest.java b/plugins/transforms/mapping/src/test/java/org/apache/hop/pipeline/transforms/multimapping/MultiMappingMetaTest.java
index e47f28b7b5..252961234d 100644
--- a/plugins/transforms/mapping/src/test/java/org/apache/hop/pipeline/transforms/multimapping/MultiMappingMetaTest.java
+++ b/plugins/transforms/mapping/src/test/java/org/apache/hop/pipeline/transforms/multimapping/MultiMappingMetaTest.java
@@ -73,7 +73,7 @@ class MultiMappingMetaTest {
     assertTrue(meta.getInputMappings().get(0).isMainDataPath());
     assertTrue(meta.getInputMappings().get(0).isRenamingOnOutput());
 
-    MultiMappingMeta copy = meta.clone();
+    MultiMappingMeta copy = (MultiMappingMeta) meta.clone();
     assertEquals(1, copy.getInputMappings().size());
     copy.getInputMappings().get(0).setInputTransformName("changed");
     assertTrue(
diff --git a/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByMeta.java b/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByMeta.java
index 11b21d7e9f..d20abcf224 100644
--- a/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByMeta.java
+++ b/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByMeta.java
@@ -74,22 +74,6 @@ public class MemoryGroupByMeta extends BaseTransformMeta<MemoryGroupBy, MemoryGr
     this.aggregates = new ArrayList<>();
   }
 
-  public MemoryGroupByMeta(MemoryGroupByMeta meta) {
-    this();
-    for (GGroup group : meta.groups) {
-      groups.add(new GGroup(group));
-    }
-    for (GAggregate aggregate : meta.aggregates) {
-      aggregates.add(new GAggregate(aggregate));
-    }
-    this.alwaysGivingBackOneRow = meta.alwaysGivingBackOneRow;
-  }
-
-  @Override
-  public MemoryGroupByMeta clone() {
-    return new MemoryGroupByMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta r,
diff --git a/plugins/transforms/mergejoin/src/main/java/org/apache/hop/pipeline/transforms/mergejoin/MergeJoinMeta.java b/plugins/transforms/mergejoin/src/main/java/org/apache/hop/pipeline/transforms/mergejoin/MergeJoinMeta.java
index 709d321157..16121a96c6 100644
--- a/plugins/transforms/mergejoin/src/main/java/org/apache/hop/pipeline/transforms/mergejoin/MergeJoinMeta.java
+++ b/plugins/transforms/mergejoin/src/main/java/org/apache/hop/pipeline/transforms/mergejoin/MergeJoinMeta.java
@@ -105,19 +105,6 @@ public class MergeJoinMeta extends BaseTransformMeta<MergeJoin, MergeJoinData> {
     keyFields2 = new ArrayList<>();
   }
 
-  @Override
-  public MergeJoinMeta clone() {
-    MergeJoinMeta meta = new MergeJoinMeta();
-
-    meta.leftTransformName = this.leftTransformName;
-    meta.rightTransformName = this.rightTransformName;
-    meta.joinType = this.joinType;
-    meta.keyFields1.addAll(this.keyFields1);
-    meta.keyFields2.addAll(this.keyFields2);
-
-    return meta;
-  }
-
   @Override
   public void searchInfoAndTargetTransforms(List<TransformMeta> transforms) {
     List<IStream> infoStreams = getTransformIOMeta().getInfoStreams();
diff --git a/plugins/transforms/mergerows/src/main/java/org/apache/hop/pipeline/transforms/mergerows/MergeRowsMeta.java b/plugins/transforms/mergerows/src/main/java/org/apache/hop/pipeline/transforms/mergerows/MergeRowsMeta.java
index b8db0961d7..2161b0f949 100644
--- a/plugins/transforms/mergerows/src/main/java/org/apache/hop/pipeline/transforms/mergerows/MergeRowsMeta.java
+++ b/plugins/transforms/mergerows/src/main/java/org/apache/hop/pipeline/transforms/mergerows/MergeRowsMeta.java
@@ -122,23 +122,6 @@ public class MergeRowsMeta extends BaseTransformMeta<MergeRows, MergeRowsData> {
     passThroughFields = new ArrayList<>();
   }
 
-  public MergeRowsMeta(MergeRowsMeta m) {
-    this();
-    this.flagField = m.flagField;
-    this.keyFields = new ArrayList<>(m.keyFields);
-    this.valueFields = new ArrayList<>(m.valueFields);
-    this.referenceTransform = m.referenceTransform;
-    this.compareTransform = m.compareTransform;
-    this.diffJsonField = m.diffJsonField;
-    this.alignInputLayouts = m.alignInputLayouts;
-    m.getPassThroughFields().forEach(f -> this.passThroughFields.add(new PassThroughField(f)));
-  }
-
-  @Override
-  public MergeRowsMeta clone() {
-    return new MergeRowsMeta(this);
-  }
-
   @Override
   public void setDefault() {
     flagField = "flagfield";
diff --git a/plugins/transforms/mergerows/src/test/java/org/apache/hop/pipeline/transforms/mergerows/MergeRowsMetaTest.java b/plugins/transforms/mergerows/src/test/java/org/apache/hop/pipeline/transforms/mergerows/MergeRowsMetaTest.java
index 52e5c11766..d8238df95c 100644
--- a/plugins/transforms/mergerows/src/test/java/org/apache/hop/pipeline/transforms/mergerows/MergeRowsMetaTest.java
+++ b/plugins/transforms/mergerows/src/test/java/org/apache/hop/pipeline/transforms/mergerows/MergeRowsMetaTest.java
@@ -74,7 +74,7 @@ class MergeRowsMetaTest {
     meta.setAlignInputLayouts(false);
     meta.getKeyFields().add("id");
 
-    MergeRowsMeta copy = meta.clone();
+    MergeRowsMeta copy = (MergeRowsMeta) meta.clone();
     assertEquals("flag", copy.getFlagField());
     assertEquals("difference", copy.getDiffJsonField());
     assertFalse(copy.isAlignInputLayouts());
diff --git a/plugins/transforms/metadata/src/main/java/org/apache/hop/pipeline/transforms/metainput/MetadataInputMeta.java b/plugins/transforms/metadata/src/main/java/org/apache/hop/pipeline/transforms/metainput/MetadataInputMeta.java
index 15912a17d5..ebfeac8f38 100644
--- a/plugins/transforms/metadata/src/main/java/org/apache/hop/pipeline/transforms/metainput/MetadataInputMeta.java
+++ b/plugins/transforms/metadata/src/main/java/org/apache/hop/pipeline/transforms/metainput/MetadataInputMeta.java
@@ -60,22 +60,6 @@ public class MetadataInputMeta extends BaseTransformMeta<MetadataInput, Metadata
     this.typeKeyFilters = new ArrayList<>();
   }
 
-  public MetadataInputMeta(MetadataInputMeta meta) {
-    this.providerFieldName = meta.providerFieldName;
-    this.typeKeyFieldName = meta.typeKeyFieldName;
-    this.typeNameFieldName = meta.typeNameFieldName;
-    this.typeDescriptionFieldName = meta.typeDescriptionFieldName;
-    this.typeClassFieldName = meta.typeClassFieldName;
-    this.nameFieldName = meta.nameFieldName;
-    this.jsonFieldName = meta.jsonFieldName;
-    this.typeKeyFilters = new ArrayList<>(meta.typeKeyFilters);
-  }
-
-  @Override
-  public MetadataInputMeta clone() {
-    return new MetadataInputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/metainject/src/main/java/org/apache/hop/pipeline/transforms/metainject/MetaInjectMeta.java b/plugins/transforms/metainject/src/main/java/org/apache/hop/pipeline/transforms/metainject/MetaInjectMeta.java
index d88244e536..0fa3ebe239 100644
--- a/plugins/transforms/metainject/src/main/java/org/apache/hop/pipeline/transforms/metainject/MetaInjectMeta.java
+++ b/plugins/transforms/metainject/src/main/java/org/apache/hop/pipeline/transforms/metainject/MetaInjectMeta.java
@@ -139,26 +139,6 @@ public class MetaInjectMeta extends BaseTransformMeta<MetaInject, MetaInjectData
     createParentFolder = true;
   }
 
-  public MetaInjectMeta(MetaInjectMeta m) {
-    this();
-    this.allowEmptyStreamOnExecution = m.allowEmptyStreamOnExecution;
-    this.createParentFolder = m.createParentFolder;
-    this.noExecution = m.noExecution;
-    this.runConfigurationName = m.runConfigurationName;
-    this.sourceTransformName = m.sourceTransformName;
-    this.streamSourceTransformName = m.streamSourceTransformName;
-    this.streamTargetTransformName = m.streamTargetTransformName;
-    this.targetFile = m.targetFile;
-    this.templateFileName = m.templateFileName;
-    m.sourceOutputFields.forEach(f -> this.sourceOutputFields.add(new MetaInjectOutputField(f)));
-    m.mappings.forEach(map -> this.mappings.add(new MetaInjectMapping(map)));
-  }
-
-  @Override
-  public Object clone() {
-    return new MetaInjectMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/metastructure/src/main/java/org/apache/hop/pipeline/transforms/metastructure/TransformMetaStructureMeta.java b/plugins/transforms/metastructure/src/main/java/org/apache/hop/pipeline/transforms/metastructure/TransformMetaStructureMeta.java
index d81b871b6e..22922733f0 100644
--- a/plugins/transforms/metastructure/src/main/java/org/apache/hop/pipeline/transforms/metastructure/TransformMetaStructureMeta.java
+++ b/plugins/transforms/metastructure/src/main/java/org/apache/hop/pipeline/transforms/metastructure/TransformMetaStructureMeta.java
@@ -123,11 +123,6 @@ public class TransformMetaStructureMeta
     originFieldName = BaseMessages.getString(PKG, "TransformMetaStructureMeta.OriginName");
   }
 
-  @Override
-  public TransformMetaStructureMeta clone() {
-    return (TransformMetaStructureMeta) super.clone();
-  }
-
   @Override
   public void check(
       List<ICheckResult> remarks,
diff --git a/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserMeta.java b/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserMeta.java
index 1c79d59f3c..23dd5ac722 100644
--- a/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserMeta.java
+++ b/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserMeta.java
@@ -95,13 +95,6 @@ public class NormaliserMeta extends BaseTransformMeta<Normaliser, NormaliserData
     this.normaliserFields = new ArrayList<>();
   }
 
-  public NormaliserMeta(NormaliserMeta meta) {
-    this();
-    for (NormaliserField field : meta.normaliserFields) {
-      normaliserFields.add(new NormaliserField(field));
-    }
-  }
-
   public Set<String> getFieldNames() {
     Set<String> fieldNames = new HashSet<>();
 
@@ -113,11 +106,6 @@ public class NormaliserMeta extends BaseTransformMeta<Normaliser, NormaliserData
     return fieldNames;
   }
 
-  @Override
-  public Object clone() {
-    return new NormaliserMeta(this);
-  }
-
   @Override
   public void setDefault() {
     this.typeField = "typefield";
diff --git a/plugins/transforms/nullif/src/main/java/org/apache/hop/pipeline/transforms/nullif/NullIfMeta.java b/plugins/transforms/nullif/src/main/java/org/apache/hop/pipeline/transforms/nullif/NullIfMeta.java
index 17c3f08b8b..5518a426d9 100644
--- a/plugins/transforms/nullif/src/main/java/org/apache/hop/pipeline/transforms/nullif/NullIfMeta.java
+++ b/plugins/transforms/nullif/src/main/java/org/apache/hop/pipeline/transforms/nullif/NullIfMeta.java
@@ -56,13 +56,6 @@ public class NullIfMeta extends BaseTransformMeta<NullIf, NullIfData> {
     this.fields = new ArrayList<>();
   }
 
-  public NullIfMeta(NullIfMeta meta) {
-    this();
-    for (NullIfField field : meta.fields) {
-      fields.add(new NullIfField(field.getName(), field.getValue()));
-    }
-  }
-
   public List<NullIfField> getFields() {
     return fields;
   }
@@ -71,11 +64,6 @@ public class NullIfMeta extends BaseTransformMeta<NullIf, NullIfData> {
     this.fields = fields;
   }
 
-  @Override
-  public Object clone() {
-    return new NullIfMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta r,
diff --git a/plugins/transforms/numberrange/src/main/java/org/apache/hop/pipeline/transforms/numberrange/NumberRangeMeta.java b/plugins/transforms/numberrange/src/main/java/org/apache/hop/pipeline/transforms/numberrange/NumberRangeMeta.java
index 4149627abb..a1a1a3214b 100644
--- a/plugins/transforms/numberrange/src/main/java/org/apache/hop/pipeline/transforms/numberrange/NumberRangeMeta.java
+++ b/plugins/transforms/numberrange/src/main/java/org/apache/hop/pipeline/transforms/numberrange/NumberRangeMeta.java
@@ -96,12 +96,6 @@ public class NumberRangeMeta extends BaseTransformMeta<NumberRange, NumberRangeD
     row.addValueMeta(mcValue);
   }
 
-  @Override
-  public Object clone() {
-    Object retval = super.clone();
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     emptyRules();
diff --git a/plugins/transforms/odata/src/main/java/org/apache/hop/pipeline/transforms/odata/ODataInputMeta.java b/plugins/transforms/odata/src/main/java/org/apache/hop/pipeline/transforms/odata/ODataInputMeta.java
index 14d5a185e5..703c87c18e 100644
--- a/plugins/transforms/odata/src/main/java/org/apache/hop/pipeline/transforms/odata/ODataInputMeta.java
+++ b/plugins/transforms/odata/src/main/java/org/apache/hop/pipeline/transforms/odata/ODataInputMeta.java
@@ -88,26 +88,6 @@ public class ODataInputMeta extends BaseTransformMeta<ODataInput, ODataInputData
     authType = "NONE";
   }
 
-  public ODataInputMeta(ODataInputMeta other) {
-    this();
-    this.url = other.url;
-    this.entitySet = other.entitySet;
-    this.authType = other.authType;
-    this.username = other.username;
-    this.password = other.password;
-    this.token = other.token;
-    this.querySelect = other.querySelect;
-    this.queryFilter = other.queryFilter;
-    this.queryOrder = other.queryOrder;
-    this.queryTop = other.queryTop;
-    this.querySkip = other.querySkip;
-    if (other.fields != null) {
-      for (ODataField f : other.fields) {
-        this.fields.add(new ODataField(f));
-      }
-    }
-  }
-
   @Override
   public void setDefault() {
     this.url = "";
diff --git a/plugins/transforms/pgp/src/main/java/org/apache/hop/pipeline/transforms/pgpdecryptstream/PGPDecryptStreamMeta.java b/plugins/transforms/pgp/src/main/java/org/apache/hop/pipeline/transforms/pgpdecryptstream/PGPDecryptStreamMeta.java
index 5fde089338..b322a8a15d 100644
--- a/plugins/transforms/pgp/src/main/java/org/apache/hop/pipeline/transforms/pgpdecryptstream/PGPDecryptStreamMeta.java
+++ b/plugins/transforms/pgp/src/main/java/org/apache/hop/pipeline/transforms/pgpdecryptstream/PGPDecryptStreamMeta.java
@@ -80,21 +80,6 @@ public class PGPDecryptStreamMeta
     resultFieldName = "result";
   }
 
-  public PGPDecryptStreamMeta(PGPDecryptStreamMeta m) {
-    this();
-    this.gpgLocation = m.gpgLocation;
-    this.passPhrase = m.passPhrase;
-    this.passPhraseFieldName = m.passPhraseFieldName;
-    this.passPhraseFromField = m.passPhraseFromField;
-    this.resultFieldName = m.resultFieldName;
-    this.streamField = m.streamField;
-  }
-
-  @Override
-  public Object clone() {
-    return new PGPDecryptStreamMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/pgp/src/main/java/org/apache/hop/pipeline/transforms/pgpencryptstream/PGPEncryptStreamMeta.java b/plugins/transforms/pgp/src/main/java/org/apache/hop/pipeline/transforms/pgpencryptstream/PGPEncryptStreamMeta.java
index d3fb29f768..32d5836f88 100644
--- a/plugins/transforms/pgp/src/main/java/org/apache/hop/pipeline/transforms/pgpencryptstream/PGPEncryptStreamMeta.java
+++ b/plugins/transforms/pgp/src/main/java/org/apache/hop/pipeline/transforms/pgpencryptstream/PGPEncryptStreamMeta.java
@@ -80,21 +80,6 @@ public class PGPEncryptStreamMeta
     this.resultFieldName = "result";
   }
 
-  public PGPEncryptStreamMeta(PGPEncryptStreamMeta m) {
-    this();
-    this.gpgLocation = m.gpgLocation;
-    this.keyName = m.keyName;
-    this.keyNameFieldName = m.keyNameFieldName;
-    this.keyNameInField = m.keyNameInField;
-    this.resultFieldName = m.resultFieldName;
-    this.streamField = m.streamField;
-  }
-
-  @Override
-  public Object clone() {
-    return new PGPEncryptStreamMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/propertyinput/src/main/java/org/apache/hop/pipeline/transforms/propertyinput/PropertyInputMeta.java b/plugins/transforms/propertyinput/src/main/java/org/apache/hop/pipeline/transforms/propertyinput/PropertyInputMeta.java
index debe1df03d..dddbb1cf02 100644
--- a/plugins/transforms/propertyinput/src/main/java/org/apache/hop/pipeline/transforms/propertyinput/PropertyInputMeta.java
+++ b/plugins/transforms/propertyinput/src/main/java/org/apache/hop/pipeline/transforms/propertyinput/PropertyInputMeta.java
@@ -164,40 +164,6 @@ public class PropertyInputMeta extends BaseTransformMeta<PropertyInput, Property
     inputFields = new ArrayList<>();
   }
 
-  public PropertyInputMeta(PropertyInputMeta m) {
-    this();
-    this.encoding = m.encoding;
-    this.fileType = m.fileType;
-    this.includingFilename = m.includingFilename;
-    this.resettingRowNumber = m.resettingRowNumber;
-    this.resolvingValueVariable = m.resolvingValueVariable;
-    this.filenameField = m.filenameField;
-    this.includeRowNumber = m.includeRowNumber;
-    this.rowNumberField = m.rowNumberField;
-    this.rowLimit = m.rowLimit;
-    this.fileField = m.fileField;
-    this.addResult = m.addResult;
-    this.dynamicFilenameField = m.dynamicFilenameField;
-    this.includeIniSection = m.includeIniSection;
-    this.iniSectionField = m.iniSectionField;
-    this.section = m.section;
-    this.shortFileFieldName = m.shortFileFieldName;
-    this.pathFieldName = m.pathFieldName;
-    this.hiddenFieldName = m.hiddenFieldName;
-    this.lastModificationTimeFieldName = m.lastModificationTimeFieldName;
-    this.uriNameFieldName = m.uriNameFieldName;
-    this.rootUriNameFieldName = m.rootUriNameFieldName;
-    this.extensionFieldName = m.extensionFieldName;
-    this.sizeFieldName = m.sizeFieldName;
-    m.files.forEach(f -> this.files.add(new PIFile(f)));
-    m.inputFields.forEach(f -> this.inputFields.add(new PIField(f)));
-  }
-
-  @Override
-  public PropertyInputMeta clone() {
-    return new PropertyInputMeta(this);
-  }
-
   @Override
   public void setDefault() {
     shortFileFieldName = null;
diff --git a/plugins/transforms/propertyoutput/src/main/java/org/apache/hop/pipeline/transforms/propertyoutput/PropertyOutputMeta.java b/plugins/transforms/propertyoutput/src/main/java/org/apache/hop/pipeline/transforms/propertyoutput/PropertyOutputMeta.java
index befb8f0e0a..0693fc56a7 100644
--- a/plugins/transforms/propertyoutput/src/main/java/org/apache/hop/pipeline/transforms/propertyoutput/PropertyOutputMeta.java
+++ b/plugins/transforms/propertyoutput/src/main/java/org/apache/hop/pipeline/transforms/propertyoutput/PropertyOutputMeta.java
@@ -137,21 +137,6 @@ public class PropertyOutputMeta extends BaseTransformMeta<PropertyOutput, Proper
     this.fileDetails = new FileDetails();
   }
 
-  public PropertyOutputMeta(PropertyOutputMeta m) {
-    this();
-    this.comment = m.comment;
-    this.keyField = m.keyField;
-    this.valueField = m.valueField;
-    this.fileNameInField = m.fileNameInField;
-    this.fileNameField = m.fileNameField;
-    this.fileDetails = new FileDetails(m.fileDetails);
-  }
-
-  @Override
-  public Object clone() {
-    return new PropertyOutputMeta(this);
-  }
-
   public String[] getFiles(IVariables variables) {
     int copies = 1;
     int parts = 1;
diff --git a/plugins/transforms/randomvalue/src/main/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueMeta.java b/plugins/transforms/randomvalue/src/main/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueMeta.java
index 885c0f22ac..7e6f00ad34 100644
--- a/plugins/transforms/randomvalue/src/main/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueMeta.java
+++ b/plugins/transforms/randomvalue/src/main/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueMeta.java
@@ -70,11 +70,6 @@ public class RandomValueMeta extends BaseTransformMeta<RandomValue, RandomValueD
     m.fields.forEach(f -> this.fields.add(new RVField(f)));
   }
 
-  @Override
-  public RandomValueMeta clone() {
-    return new RandomValueMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/randomvalue/src/test/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueMetaTest.java b/plugins/transforms/randomvalue/src/test/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueMetaTest.java
index 9740ea2bed..b7b4b3bb90 100644
--- a/plugins/transforms/randomvalue/src/test/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueMetaTest.java
+++ b/plugins/transforms/randomvalue/src/test/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueMetaTest.java
@@ -123,7 +123,7 @@ class RandomValueMetaTest {
   void testCloneDeepCopy() {
     RandomValueMeta meta = sampleMeta();
 
-    RandomValueMeta cloned = meta.clone();
+    RandomValueMeta cloned = (RandomValueMeta) meta.clone();
 
     assertNotSame(meta, cloned);
     assertEquals(meta.getSeed(), cloned.getSeed());
diff --git a/plugins/transforms/regexeval/src/main/java/org/apache/hop/pipeline/transforms/regexeval/RegexEvalMeta.java b/plugins/transforms/regexeval/src/main/java/org/apache/hop/pipeline/transforms/regexeval/RegexEvalMeta.java
index 02755eb59b..b281065abe 100644
--- a/plugins/transforms/regexeval/src/main/java/org/apache/hop/pipeline/transforms/regexeval/RegexEvalMeta.java
+++ b/plugins/transforms/regexeval/src/main/java/org/apache/hop/pipeline/transforms/regexeval/RegexEvalMeta.java
@@ -186,29 +186,6 @@ public class RegexEvalMeta extends BaseTransformMeta<RegexEval, RegexEvalData> {
     regexFields = new ArrayList<>();
   }
 
-  public RegexEvalMeta(RegexEvalMeta m) {
-    this();
-    this.script = m.script;
-    this.matcher = m.matcher;
-    this.resultFieldName = m.resultFieldName;
-    this.usingVariables = m.usingVariables;
-    this.allowingCaptureGroups = m.allowingCaptureGroups;
-    this.replacingFields = m.replacingFields;
-    this.canonicalEqualityEnabled = m.canonicalEqualityEnabled;
-    this.caseInsensitive = m.caseInsensitive;
-    this.commentingEnabled = m.commentingEnabled;
-    this.dotAllEnabled = m.dotAllEnabled;
-    this.multiLine = m.multiLine;
-    this.unicode = m.unicode;
-    this.unixLineEndings = m.unixLineEndings;
-    m.regexFields.forEach(field -> this.regexFields.add(new RegexField(field)));
-  }
-
-  @Override
-  public RegexEvalMeta clone() {
-    return new RegexEvalMeta(this);
-  }
-
   public String getRegexOptions() {
     StringBuilder options = new StringBuilder();
 
diff --git a/plugins/transforms/repeatfields/src/main/java/org/apache/hop/pipeline/transforms/repeatfields/RepeatFieldsMeta.java b/plugins/transforms/repeatfields/src/main/java/org/apache/hop/pipeline/transforms/repeatfields/RepeatFieldsMeta.java
index fc1409363a..e717e19f6c 100644
--- a/plugins/transforms/repeatfields/src/main/java/org/apache/hop/pipeline/transforms/repeatfields/RepeatFieldsMeta.java
+++ b/plugins/transforms/repeatfields/src/main/java/org/apache/hop/pipeline/transforms/repeatfields/RepeatFieldsMeta.java
@@ -72,19 +72,6 @@ public class RepeatFieldsMeta extends BaseTransformMeta<RepeatFields, RepeatFiel
     this.repeats = new ArrayList<>();
   }
 
-  public RepeatFieldsMeta(RepeatFieldsMeta m) {
-    this();
-    this.groupFields.addAll(m.groupFields);
-    for (Repeat repeat : m.repeats) {
-      this.repeats.add(new Repeat(repeat));
-    }
-  }
-
-  @Override
-  public Object clone() {
-    return new RepeatFieldsMeta(this);
-  }
-
   /**
    * We only add an optional target field containing a corrected copy of the source field.
    *
diff --git a/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringMeta.java b/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringMeta.java
index b256a781ba..b914b95b1f 100644
--- a/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringMeta.java
+++ b/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringMeta.java
@@ -61,16 +61,6 @@ public class ReplaceStringMeta extends BaseTransformMeta<ReplaceString, ReplaceS
     this.fields = new ArrayList<>();
   }
 
-  public ReplaceStringMeta(ReplaceStringMeta m) {
-    this();
-    m.fields.forEach(f -> this.fields.add(new RSField(f)));
-  }
-
-  @Override
-  public ReplaceStringMeta clone() {
-    return new ReplaceStringMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/reservoirsampling/src/main/java/org/apache/hop/pipeline/transforms/reservoirsampling/ReservoirSamplingMeta.java b/plugins/transforms/reservoirsampling/src/main/java/org/apache/hop/pipeline/transforms/reservoirsampling/ReservoirSamplingMeta.java
index 9109425669..f514052b61 100644
--- a/plugins/transforms/reservoirsampling/src/main/java/org/apache/hop/pipeline/transforms/reservoirsampling/ReservoirSamplingMeta.java
+++ b/plugins/transforms/reservoirsampling/src/main/java/org/apache/hop/pipeline/transforms/reservoirsampling/ReservoirSamplingMeta.java
@@ -60,12 +60,6 @@ public class ReservoirSamplingMeta
     super();
   }
 
-  public ReservoirSamplingMeta(ReservoirSamplingMeta m) {
-    this();
-    this.sampleSize = m.sampleSize;
-    this.seed = m.seed;
-  }
-
   /** Set the defaults for this transform. */
   @Override
   public void setDefault() {
@@ -73,16 +67,6 @@ public class ReservoirSamplingMeta
     seed = "1";
   }
 
-  /**
-   * Clone this transform's meta data
-   *
-   * @return the cloned meta data
-   */
-  @Override
-  public ReservoirSamplingMeta clone() {
-    return new ReservoirSamplingMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java b/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
index 6a3d70f491..3c70ab749a 100644
--- a/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
+++ b/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
@@ -299,13 +299,6 @@ public class RestMeta extends BaseTransformMeta<Rest, RestData> {
     this.retryMethods = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    RestMeta retval = (RestMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     headerFields = new ArrayList<>();
diff --git a/plugins/transforms/rowgenerator/src/main/java/org/apache/hop/pipeline/transforms/rowgenerator/RowGeneratorMeta.java b/plugins/transforms/rowgenerator/src/main/java/org/apache/hop/pipeline/transforms/rowgenerator/RowGeneratorMeta.java
index 6be2aed62d..3ddfa33e76 100644
--- a/plugins/transforms/rowgenerator/src/main/java/org/apache/hop/pipeline/transforms/rowgenerator/RowGeneratorMeta.java
+++ b/plugins/transforms/rowgenerator/src/main/java/org/apache/hop/pipeline/transforms/rowgenerator/RowGeneratorMeta.java
@@ -93,23 +93,6 @@ public class RowGeneratorMeta extends BaseTransformMeta<RowGenerator, RowGenerat
     lastTimeField = "FiveSecondsAgo";
   }
 
-  public RowGeneratorMeta(RowGeneratorMeta m) {
-    this.neverEnding = m.neverEnding;
-    this.intervalInMs = m.intervalInMs;
-    this.rowTimeField = m.rowTimeField;
-    this.lastTimeField = m.lastTimeField;
-    this.rowLimit = m.rowLimit;
-    this.fields = new ArrayList<>();
-    for (GeneratorField field : m.fields) {
-      this.fields.add(new GeneratorField(field));
-    }
-  }
-
-  @Override
-  public RowGeneratorMeta clone() {
-    return new RowGeneratorMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/rowsfromresult/src/main/java/org/apache/hop/pipeline/transforms/rowsfromresult/RowsFromResultMeta.java b/plugins/transforms/rowsfromresult/src/main/java/org/apache/hop/pipeline/transforms/rowsfromresult/RowsFromResultMeta.java
index 10d2eff76e..eba09bde1e 100644
--- a/plugins/transforms/rowsfromresult/src/main/java/org/apache/hop/pipeline/transforms/rowsfromresult/RowsFromResultMeta.java
+++ b/plugins/transforms/rowsfromresult/src/main/java/org/apache/hop/pipeline/transforms/rowsfromresult/RowsFromResultMeta.java
@@ -104,16 +104,6 @@ public class RowsFromResultMeta extends BaseTransformMeta<RowsFromResult, RowsFr
     this.resultFields = new ArrayList<>();
   }
 
-  public RowsFromResultMeta(RowsFromResultMeta m) {
-    this();
-    m.resultFields.forEach(field -> this.resultFields.add(new ResultRowField(field)));
-  }
-
-  @Override
-  public Object clone() {
-    return new RowsFromResultMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta r,
diff --git a/plugins/transforms/rowstoresult/src/main/java/org/apache/hop/pipeline/transforms/rowstoresult/RowsToResultMeta.java b/plugins/transforms/rowstoresult/src/main/java/org/apache/hop/pipeline/transforms/rowstoresult/RowsToResultMeta.java
index c33e2b1b5d..1aefe6bb09 100644
--- a/plugins/transforms/rowstoresult/src/main/java/org/apache/hop/pipeline/transforms/rowstoresult/RowsToResultMeta.java
+++ b/plugins/transforms/rowstoresult/src/main/java/org/apache/hop/pipeline/transforms/rowstoresult/RowsToResultMeta.java
@@ -53,12 +53,6 @@ public class RowsToResultMeta extends BaseTransformMeta<RowsToResult, RowsToResu
     readData(transformNode);
   }
 
-  @Override
-  public Object clone() {
-    Object retval = super.clone();
-    return retval;
-  }
-
   private void readData(Node transformNode) {
     // Do nothing
   }
diff --git a/plugins/transforms/samplerows/src/main/java/org/apache/hop/pipeline/transforms/samplerows/SampleRowsMeta.java b/plugins/transforms/samplerows/src/main/java/org/apache/hop/pipeline/transforms/samplerows/SampleRowsMeta.java
index 92194c9afa..9fcbb44046 100644
--- a/plugins/transforms/samplerows/src/main/java/org/apache/hop/pipeline/transforms/samplerows/SampleRowsMeta.java
+++ b/plugins/transforms/samplerows/src/main/java/org/apache/hop/pipeline/transforms/samplerows/SampleRowsMeta.java
@@ -58,12 +58,6 @@ public class SampleRowsMeta extends BaseTransformMeta<SampleRows, SampleRowsData
     super(); // allocate BaseTransformMeta
   }
 
-  @Override
-  public Object clone() {
-    Object retval = super.clone();
-    return retval;
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/sasinput/src/main/java/org/apache/hop/pipeline/transforms/sasinput/SasInputMeta.java b/plugins/transforms/sasinput/src/main/java/org/apache/hop/pipeline/transforms/sasinput/SasInputMeta.java
index bf3a6716fa..b3ad283531 100644
--- a/plugins/transforms/sasinput/src/main/java/org/apache/hop/pipeline/transforms/sasinput/SasInputMeta.java
+++ b/plugins/transforms/sasinput/src/main/java/org/apache/hop/pipeline/transforms/sasinput/SasInputMeta.java
@@ -73,21 +73,6 @@ public class SasInputMeta extends BaseTransformMeta<SasInput, SasInputData> {
     outputFields = new ArrayList<>();
   }
 
-  public SasInputMeta(SasInputMeta m) {
-    this();
-    this.acceptingField = m.acceptingField;
-    this.metadataFilename = m.metadataFilename;
-    this.limit = m.limit;
-    for (SasInputField field : m.outputFields) {
-      outputFields.add(new SasInputField(field));
-    }
-  }
-
-  @Override
-  public SasInputMeta clone() {
-    return new SasInputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/script/src/main/java/org/apache/hop/pipeline/transforms/script/ScriptMeta.java b/plugins/transforms/script/src/main/java/org/apache/hop/pipeline/transforms/script/ScriptMeta.java
index 102a403eef..1fe89bc3ab 100644
--- a/plugins/transforms/script/src/main/java/org/apache/hop/pipeline/transforms/script/ScriptMeta.java
+++ b/plugins/transforms/script/src/main/java/org/apache/hop/pipeline/transforms/script/ScriptMeta.java
@@ -62,18 +62,6 @@ public class ScriptMeta extends BaseTransformMeta<Script, ScriptData> implements
     fields = new ArrayList<>();
   }
 
-  public ScriptMeta(ScriptMeta m) {
-    this();
-    this.languageName = m.languageName;
-    m.scripts.forEach(s -> this.scripts.add(new SScript(s)));
-    m.fields.forEach(f -> this.fields.add(new SField(f)));
-  }
-
-  @Override
-  public ScriptMeta clone() {
-    return new ScriptMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/script/src/test/java/org/apache/hop/pipeline/transforms/script/ScriptMetaTest.java b/plugins/transforms/script/src/test/java/org/apache/hop/pipeline/transforms/script/ScriptMetaTest.java
index 624d1f900e..350e4eb024 100644
--- a/plugins/transforms/script/src/test/java/org/apache/hop/pipeline/transforms/script/ScriptMetaTest.java
+++ b/plugins/transforms/script/src/test/java/org/apache/hop/pipeline/transforms/script/ScriptMetaTest.java
@@ -114,7 +114,7 @@ class ScriptMetaTest {
         .add(new ScriptMeta.SScript(ScriptMeta.ScriptType.TRANSFORM_SCRIPT, "s1", "1+1"));
     meta.getFields().add(createField("f1", "Integer"));
 
-    ScriptMeta cloned = meta.clone();
+    ScriptMeta cloned = (ScriptMeta) meta.clone();
     assertNotNull(cloned);
     assertFalse(cloned == meta);
     assertEquals("Groovy", cloned.getLanguageName());
diff --git a/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesMeta.java b/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesMeta.java
index 643c2a38a3..899fcc973a 100644
--- a/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesMeta.java
+++ b/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesMeta.java
@@ -69,16 +69,6 @@ public class SelectValuesMeta extends BaseTransformMeta<SelectValues, SelectValu
     selectOption = new SelectOptions();
   }
 
-  @Override
-  public SelectValuesMeta clone() {
-    return new SelectValuesMeta(this);
-  }
-
-  public SelectValuesMeta(SelectValuesMeta m) {
-    super.clone();
-    this.selectOption = new SelectOptions(m.getSelectOption());
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/serverstatus/src/main/java/org/apache/hop/pipeline/transforms/serverstatus/GetServerStatusMeta.java b/plugins/transforms/serverstatus/src/main/java/org/apache/hop/pipeline/transforms/serverstatus/GetServerStatusMeta.java
index 3a4820d6a2..886f3364db 100644
--- a/plugins/transforms/serverstatus/src/main/java/org/apache/hop/pipeline/transforms/serverstatus/GetServerStatusMeta.java
+++ b/plugins/transforms/serverstatus/src/main/java/org/apache/hop/pipeline/transforms/serverstatus/GetServerStatusMeta.java
@@ -112,31 +112,6 @@ public class GetServerStatusMeta extends BaseTransformMeta<GetServerStatus, GetS
     responseNsField = "responseNs";
   }
 
-  public GetServerStatusMeta(GetServerStatusMeta meta) {
-    this.serverField = meta.serverField;
-    this.errorMessageField = meta.errorMessageField;
-    this.statusDescriptionField = meta.statusDescriptionField;
-    this.serverLoadField = meta.serverLoadField;
-    this.memoryFreeField = meta.memoryFreeField;
-    this.memoryTotalField = meta.memoryTotalField;
-    this.cpuCoresField = meta.cpuCoresField;
-    this.cpuProcessTimeField = meta.cpuProcessTimeField;
-    this.osNameField = meta.osNameField;
-    this.osVersionField = meta.osVersionField;
-    this.osArchitectureField = meta.osArchitectureField;
-    this.activePipelinesField = meta.activePipelinesField;
-    this.finishedPipelinesField = meta.finishedPipelinesField;
-    this.activeWorkflowsField = meta.activeWorkflowsField;
-    this.finishedWorkflowsField = meta.finishedWorkflowsField;
-    this.availableField = meta.availableField;
-    this.responseNsField = meta.responseNsField;
-  }
-
-  @Override
-  public GetServerStatusMeta clone() {
-    return new GetServerStatusMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/setvaluefield/src/main/java/org/apache/hop/pipeline/transforms/setvaluefield/SetValueFieldMeta.java b/plugins/transforms/setvaluefield/src/main/java/org/apache/hop/pipeline/transforms/setvaluefield/SetValueFieldMeta.java
index 07aa058abd..bbc1b18866 100644
--- a/plugins/transforms/setvaluefield/src/main/java/org/apache/hop/pipeline/transforms/setvaluefield/SetValueFieldMeta.java
+++ b/plugins/transforms/setvaluefield/src/main/java/org/apache/hop/pipeline/transforms/setvaluefield/SetValueFieldMeta.java
@@ -53,13 +53,6 @@ public class SetValueFieldMeta extends BaseTransformMeta<SetValueField, SetValue
     super();
   }
 
-  public SetValueFieldMeta(SetValueFieldMeta clone) {
-    super();
-    for (SetField field : clone.getFields()) {
-      fields.add(new SetField(field));
-    }
-  }
-
   public List<SetField> getFields() {
     return fields;
   }
@@ -68,11 +61,6 @@ public class SetValueFieldMeta extends BaseTransformMeta<SetValueField, SetValue
     this.fields = fields;
   }
 
-  @Override
-  public Object clone() {
-    return new SetValueFieldMeta(this);
-  }
-
   @Override
   public void setDefault() {
     fields = new ArrayList<>();
diff --git a/plugins/transforms/sort/src/main/java/org/apache/hop/pipeline/transforms/sort/SortRowsMeta.java b/plugins/transforms/sort/src/main/java/org/apache/hop/pipeline/transforms/sort/SortRowsMeta.java
index 02507087dd..43bad10458 100644
--- a/plugins/transforms/sort/src/main/java/org/apache/hop/pipeline/transforms/sort/SortRowsMeta.java
+++ b/plugins/transforms/sort/src/main/java/org/apache/hop/pipeline/transforms/sort/SortRowsMeta.java
@@ -108,23 +108,6 @@ public class SortRowsMeta extends BaseTransformMeta<SortRows, SortRowsData>
     onlyPassingUniqueRows = false;
   }
 
-  public SortRowsMeta(SortRowsMeta m) {
-    this();
-    this.directory = m.directory;
-    this.prefix = m.prefix;
-    this.sortSize = m.sortSize;
-    this.freeMemoryLimit = m.freeMemoryLimit;
-    this.onlyPassingUniqueRows = m.onlyPassingUniqueRows;
-    this.compressFiles = m.compressFiles;
-    this.compressFilesVariable = m.compressFilesVariable;
-    m.sortFields.forEach(f -> sortFields.add(new SortRowsField(f)));
-  }
-
-  @Override
-  public Object clone() {
-    return new SortRowsMeta(this);
-  }
-
   /**
    * Returns the collation strength based on the passed in locale. Package protected for testing
    * purposes
diff --git a/plugins/transforms/sortedmerge/src/main/java/org/apache/hop/pipeline/transforms/sortedmerge/SortedMergeMeta.java b/plugins/transforms/sortedmerge/src/main/java/org/apache/hop/pipeline/transforms/sortedmerge/SortedMergeMeta.java
index 961b86b29d..dbf7a35309 100644
--- a/plugins/transforms/sortedmerge/src/main/java/org/apache/hop/pipeline/transforms/sortedmerge/SortedMergeMeta.java
+++ b/plugins/transforms/sortedmerge/src/main/java/org/apache/hop/pipeline/transforms/sortedmerge/SortedMergeMeta.java
@@ -62,16 +62,6 @@ public class SortedMergeMeta extends BaseTransformMeta<SortedMerge, SortedMergeD
     mergeFields = new ArrayList<>();
   }
 
-  public SortedMergeMeta(SortedMergeMeta m) {
-    this();
-    m.mergeFields.forEach(f -> this.mergeFields.add(new MergeField(f)));
-  }
-
-  @Override
-  public Object clone() {
-    return new SortedMergeMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/sql/src/main/java/org/apache/hop/pipeline/transforms/sql/ExecSqlMeta.java b/plugins/transforms/sql/src/main/java/org/apache/hop/pipeline/transforms/sql/ExecSqlMeta.java
index 0e79b688aa..69f18a65c8 100644
--- a/plugins/transforms/sql/src/main/java/org/apache/hop/pipeline/transforms/sql/ExecSqlMeta.java
+++ b/plugins/transforms/sql/src/main/java/org/apache/hop/pipeline/transforms/sql/ExecSqlMeta.java
@@ -247,12 +247,6 @@ public class ExecSqlMeta extends BaseTransformMeta<ExecSql, ExecSqlData> {
     this.updateField = updateField;
   }
 
-  @Override
-  public Object clone() {
-    ExecSqlMeta retval = (ExecSqlMeta) super.clone();
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     sql = "";
diff --git a/plugins/transforms/standardizephonenumber/src/main/java/org/apache/hop/pipeline/transforms/standardizephonenumber/StandardizePhoneNumberMeta.java b/plugins/transforms/standardizephonenumber/src/main/java/org/apache/hop/pipeline/transforms/standardizephonenumber/StandardizePhoneNumberMeta.java
index 982ba45ecf..02d54e6164 100644
--- a/plugins/transforms/standardizephonenumber/src/main/java/org/apache/hop/pipeline/transforms/standardizephonenumber/StandardizePhoneNumberMeta.java
+++ b/plugins/transforms/standardizephonenumber/src/main/java/org/apache/hop/pipeline/transforms/standardizephonenumber/StandardizePhoneNumberMeta.java
@@ -75,19 +75,6 @@ public class StandardizePhoneNumberMeta
     super();
   }
 
-  public StandardizePhoneNumberMeta(StandardizePhoneNumberMeta meta) {
-    super();
-
-    for (StandardizePhoneField field : meta.getFields()) {
-      fields.add(new StandardizePhoneField(field));
-    }
-  }
-
-  @Override
-  public Object clone() {
-    return new StandardizePhoneNumberMeta(this);
-  }
-
   @Override
   public void setDefault() {
     // Do nothing
diff --git a/plugins/transforms/streamlookup/src/main/java/org/apache/hop/pipeline/transforms/streamlookup/StreamLookupMeta.java b/plugins/transforms/streamlookup/src/main/java/org/apache/hop/pipeline/transforms/streamlookup/StreamLookupMeta.java
index 8e93e083bc..f1d9a6796c 100644
--- a/plugins/transforms/streamlookup/src/main/java/org/apache/hop/pipeline/transforms/streamlookup/StreamLookupMeta.java
+++ b/plugins/transforms/streamlookup/src/main/java/org/apache/hop/pipeline/transforms/streamlookup/StreamLookupMeta.java
@@ -112,11 +112,6 @@ public class StreamLookupMeta extends BaseTransformMeta<StreamLookup, StreamLook
     this.lookup = new Lookup(m.lookup);
   }
 
-  @Override
-  public Object clone() {
-    return new StreamLookupMeta(this);
-  }
-
   /**
    * Keeps {@link #sourceTransformName} in sync when the lookup info stream is repointed from the
    * canvas (e.g. hop split, detach, drawing the info hop). Without this, {@link
diff --git a/plugins/transforms/streamschemamerge/src/main/java/org/apache/hop/pipeline/transforms/streamschemamerge/StreamSchemaMeta.java b/plugins/transforms/streamschemamerge/src/main/java/org/apache/hop/pipeline/transforms/streamschemamerge/StreamSchemaMeta.java
index 63d8252ec8..9f24cc73f1 100644
--- a/plugins/transforms/streamschemamerge/src/main/java/org/apache/hop/pipeline/transforms/streamschemamerge/StreamSchemaMeta.java
+++ b/plugins/transforms/streamschemamerge/src/main/java/org/apache/hop/pipeline/transforms/streamschemamerge/StreamSchemaMeta.java
@@ -79,25 +79,6 @@ public class StreamSchemaMeta extends BaseTransformMeta<StreamSchema, StreamSche
     transformsToMerge = new ArrayList<>();
   }
 
-  public StreamSchemaMeta(StreamSchemaMeta m) {
-    this();
-    m.transformsToMerge.forEach(t -> this.transformsToMerge.add(new TransformToMerge(t)));
-  }
-
-  /**
-   * This method is used when a transform is duplicated in Spoon. It needs to return a deep copy of
-   * this transform meta object. Be sure to create proper deep copies if the transform configuration
-   * is stored in modifiable objects.
-   *
-   * <p>See RowGeneratorMeta.clone() for an example on creating a deep copy.
-   *
-   * @return a deep copy of this
-   */
-  @Override
-  public StreamSchemaMeta clone() {
-    return new StreamSchemaMeta(this);
-  }
-
   /**
    * Prevents error box from popping up when sending in different row formats. Note you will still
    * get an error if you try to run the pipeline in safe mode.
diff --git a/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutMeta.java b/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutMeta.java
index a5338ac4ac..1b4bf18b69 100644
--- a/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutMeta.java
+++ b/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutMeta.java
@@ -60,18 +60,6 @@ public class StringCutMeta extends BaseTransformMeta<StringCut, StringCutData> {
     fields = new ArrayList<>();
   }
 
-  public StringCutMeta(StringCutMeta obj) {
-    fields = new ArrayList<>();
-    for (StringCutField field : obj.fields) {
-      this.fields.add(new StringCutField(field));
-    }
-  }
-
-  @Override
-  public Object clone() {
-    return new StringCutMeta(this);
-  }
-
   /**
    * Gets fields
    *
diff --git a/plugins/transforms/stringoperations/src/main/java/org/apache/hop/pipeline/transforms/stringoperations/StringOperationsMeta.java b/plugins/transforms/stringoperations/src/main/java/org/apache/hop/pipeline/transforms/stringoperations/StringOperationsMeta.java
index 5b79086e33..125a924271 100644
--- a/plugins/transforms/stringoperations/src/main/java/org/apache/hop/pipeline/transforms/stringoperations/StringOperationsMeta.java
+++ b/plugins/transforms/stringoperations/src/main/java/org/apache/hop/pipeline/transforms/stringoperations/StringOperationsMeta.java
@@ -73,16 +73,6 @@ public class StringOperationsMeta
     this.operations = new ArrayList<>();
   }
 
-  public StringOperationsMeta(StringOperationsMeta m) {
-    this();
-    m.operations.forEach(op -> this.operations.add(new StringOperation(op)));
-  }
-
-  @Override
-  public Object clone() {
-    return new StringOperationsMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/surefirereport/src/main/java/org/apache/hop/pipeline/transforms/surefirereport/SurefireReportOutputMeta.java b/plugins/transforms/surefirereport/src/main/java/org/apache/hop/pipeline/transforms/surefirereport/SurefireReportOutputMeta.java
index e16c7c3599..199b73350d 100644
--- a/plugins/transforms/surefirereport/src/main/java/org/apache/hop/pipeline/transforms/surefirereport/SurefireReportOutputMeta.java
+++ b/plugins/transforms/surefirereport/src/main/java/org/apache/hop/pipeline/transforms/surefirereport/SurefireReportOutputMeta.java
@@ -112,11 +112,6 @@ public class SurefireReportOutputMeta
     super();
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   @Override
   public void setDefault() {
     filename = "${IT_SUREFIRE_DIR}/surefile_${PROJECT_NAME}.xml";
diff --git a/plugins/transforms/switchcase/src/main/java/org/apache/hop/pipeline/transforms/switchcase/SwitchCaseMeta.java b/plugins/transforms/switchcase/src/main/java/org/apache/hop/pipeline/transforms/switchcase/SwitchCaseMeta.java
index a784dabc88..6b34c81076 100644
--- a/plugins/transforms/switchcase/src/main/java/org/apache/hop/pipeline/transforms/switchcase/SwitchCaseMeta.java
+++ b/plugins/transforms/switchcase/src/main/java/org/apache/hop/pipeline/transforms/switchcase/SwitchCaseMeta.java
@@ -111,25 +111,6 @@ public class SwitchCaseMeta extends BaseTransformMeta<SwitchCase, SwitchCaseData
     caseTargets = new ArrayList<>();
   }
 
-  public SwitchCaseMeta(SwitchCaseMeta m) {
-    this();
-    this.fieldName = m.fieldName;
-    this.caseValueType = m.caseValueType;
-    this.caseValueFormat = m.caseValueFormat;
-    this.caseValueDecimal = m.caseValueDecimal;
-    this.caseValueGroup = m.caseValueGroup;
-    this.defaultTargetTransformName = m.defaultTargetTransformName;
-    this.usingContains = m.usingContains;
-    for (SwitchCaseTarget target : m.caseTargets) {
-      this.caseTargets.add(new SwitchCaseTarget(target));
-    }
-  }
-
-  @Override
-  public SwitchCaseMeta clone() {
-    return new SwitchCaseMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeMeta.java b/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeMeta.java
index db3bc32e02..61b029d01d 100644
--- a/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeMeta.java
+++ b/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeMeta.java
@@ -130,25 +130,6 @@ public class SynchronizeAfterMergeMeta
     this.commitSize = "100";
   }
 
-  public SynchronizeAfterMergeMeta(SynchronizeAfterMergeMeta m) {
-    this.commitSize = m.commitSize;
-    this.connection = m.connection;
-    this.lookup = new Lookup(m.lookup);
-    this.orderDelete = m.orderDelete;
-    this.orderInsert = m.orderInsert;
-    this.orderUpdate = m.orderUpdate;
-    this.performingLookup = m.performingLookup;
-    this.tableNameField = m.tableNameField;
-    this.tableNameInField = m.tableNameInField;
-    this.usingBatchUpdates = m.usingBatchUpdates;
-    this.operationOrderField = m.operationOrderField;
-  }
-
-  @Override
-  public Object clone() {
-    return new SynchronizeAfterMergeMeta(this);
-  }
-
   @Override
   public void check(
       List<ICheckResult> remarks,
diff --git a/plugins/transforms/systemdata/src/main/java/org/apache/hop/pipeline/transforms/systemdata/SystemDataMeta.java b/plugins/transforms/systemdata/src/main/java/org/apache/hop/pipeline/transforms/systemdata/SystemDataMeta.java
index 1a9890eed6..5fc34f773d 100644
--- a/plugins/transforms/systemdata/src/main/java/org/apache/hop/pipeline/transforms/systemdata/SystemDataMeta.java
+++ b/plugins/transforms/systemdata/src/main/java/org/apache/hop/pipeline/transforms/systemdata/SystemDataMeta.java
@@ -67,11 +67,6 @@ public class SystemDataMeta extends BaseTransformMeta<SystemData, SystemDataData
     fields = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    return new SystemDataMeta(this);
-  }
-
   public SystemDataMeta(SystemDataMeta m) {
     this();
     m.fields.forEach(f -> fields.add(new SystemInfoField(f)));
diff --git a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMeta.java b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMeta.java
index 58c9e073df..d891627c3b 100644
--- a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMeta.java
+++ b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMeta.java
@@ -103,22 +103,6 @@ public class TableInputMeta extends BaseTransformMeta<TableInput, TableInputData
     super();
   }
 
-  public TableInputMeta(TableInputMeta m) {
-    this();
-    this.connection = m.connection;
-    this.executeEachInputRow = m.executeEachInputRow;
-    this.lookup = m.lookup;
-    this.rowLimit = m.rowLimit;
-    this.sql = m.sql;
-    this.sqlFromFile = m.sqlFromFile;
-    this.variableReplacementActive = m.variableReplacementActive;
-  }
-
-  @Override
-  public Object clone() {
-    return new TableInputMeta(this);
-  }
-
   @Override
   public void setDefault() {
     sql = "SELECT <values> FROM <table name> WHERE <conditions>";
diff --git a/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputMeta.java b/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputMeta.java
index 4c229f66fc..96ff76ce0c 100644
--- a/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputMeta.java
+++ b/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputMeta.java
@@ -243,11 +243,6 @@ public class TableOutputMeta extends BaseTransformMeta<TableOutput, TableOutputD
     fields = new ArrayList<>();
   }
 
-  @Override
-  public Object clone() {
-    return super.clone();
-  }
-
   @Override
   public void setDefault() {
     tableName = "";
diff --git a/plugins/transforms/tableoutput/src/test/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputChangeDetectionTest.java b/plugins/transforms/tableoutput/src/test/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputChangeDetectionTest.java
new file mode 100644
index 0000000000..053d923697
--- /dev/null
+++ b/plugins/transforms/tableoutput/src/test/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputChangeDetectionTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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
+ *
+ *      http://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.hop.pipeline.transforms.tableoutput;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Issue #8022 is not limited to the four transforms in the report: Table Output has the same
+ * shallow TableOutputMeta.clone() and the same in-place {@code info.getFields().clear()} in its
+ * dialog, so editing the field mapping is invisible to the delegate's before/after comparison too.
+ */
+class TableOutputChangeDetectionTest {
+
+  @BeforeAll
+  static void setUpBeforeClass() throws Exception {
+    HopEnvironment.init();
+  }
+
+  @Test
+  void editingTheFieldMappingIsNotDetected() throws Exception {
+    TableOutputMeta meta = new TableOutputMeta();
+    meta.setSpecifyFields(true);
+    TableOutputField field = new TableOutputField();
+    field.setFieldStream("a");
+    field.setFieldDatabase("col_a");
+    meta.getFields().add(field);
+
+    TransformMeta transformMeta = new TransformMeta("Table output", meta);
+    transformMeta.setTransformPluginId("TableOutput");
+
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    // TableOutputDialog.getInfo(): info.getFields().clear() then re-add from the grid.
+    meta.getFields().clear();
+    TableOutputField remapped = new TableOutputField();
+    remapped.setFieldStream("a");
+    remapped.setFieldDatabase("REMAPPED_COLUMN");
+    meta.getFields().add(remapped);
+
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+
+    System.out.println("before snapshot already remapped: " + before.getXml().contains("REMAPPED"));
+
+    assertTrue(
+        !before.getXml().equals(after.getXml()),
+        "remapping a Table Output column must be detected");
+  }
+}
diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputMeta.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputMeta.java
index 9fa78c4ee8..36df6ca5f8 100644
--- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputMeta.java
+++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputMeta.java
@@ -192,31 +192,6 @@ public class CsvInputMeta extends BaseTransformMeta<CsvInput, CsvInputData>
     this.bufferSize = "50000";
   }
 
-  public CsvInputMeta(CsvInputMeta m) {
-    this();
-    this.addResult = m.addResult;
-    this.bufferSize = m.bufferSize;
-    this.delimiter = m.delimiter;
-    this.enclosure = m.enclosure;
-    this.encoding = m.encoding;
-    this.filename = m.filename;
-    this.filenameField = m.filenameField;
-    this.headerPresent = m.headerPresent;
-    this.ignoreFields = m.ignoreFields;
-    this.includingFilename = m.includingFilename;
-    this.lazyConversionActive = m.lazyConversionActive;
-    this.newlinePossibleInFields = m.newlinePossibleInFields;
-    this.rowNumField = m.rowNumField;
-    this.runningInParallel = m.runningInParallel;
-    this.schemaDefinition = m.schemaDefinition;
-    m.inputFields.forEach(field -> this.inputFields.add(new CsvInputField(field)));
-  }
-
-  @Override
-  public CsvInputMeta clone() {
-    return new CsvInputMeta(this);
-  }
-
   public void getFields(
       IRowMeta rowMeta,
       String origin,
@@ -330,6 +305,15 @@ public class CsvInputMeta extends BaseTransformMeta<CsvInput, CsvInputData>
     }
   }
 
+  /**
+   * {@link org.apache.hop.pipeline.transforms.common.ICsvInputAwareMeta} declares a covariant
+   * clone(), so this override is required even though it only delegates.
+   */
+  @Override
+  public CsvInputMeta clone() {
+    return (CsvInputMeta) super.clone();
+  }
+
   @Override
   public BaseFileErrorHandling getErrorHandling() {
     return null;
diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputMeta.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputMeta.java
index b6359c1ba1..067563555b 100644
--- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputMeta.java
+++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputMeta.java
@@ -478,24 +478,13 @@ public class TextFileInputMeta
     content.rowLimit = 0L;
   }
 
-  public TextFileInputMeta(TextFileInputMeta m) {
-    this();
-    this.content = new Content(m.content);
-    this.errorCountField = m.errorCountField;
-    this.errorFieldsField = m.errorFieldsField;
-    this.errorLineSkipped = m.errorLineSkipped;
-    this.errorTextField = m.errorTextField;
-    this.ignoreFields = m.ignoreFields;
-    this.schemaDefinition = m.schemaDefinition;
-    this.additionalOutputFields = new BaseFileInputAdditionalFields(m.additionalOutputFields);
-    this.fileInput = new BaseFileInput(m.fileInput);
-    m.filters.forEach(filter -> this.filters.add(new TextFileFilter(filter)));
-    m.inputFields.forEach(f -> this.inputFields.add(new TextFileInputField(f.clone())));
-  }
-
+  /**
+   * {@link org.apache.hop.pipeline.transforms.common.ICsvInputAwareMeta} declares a covariant
+   * clone(), so this override is required even though it only delegates.
+   */
   @Override
   public TextFileInputMeta clone() {
-    return new TextFileInputMeta(this);
+    return (TextFileInputMeta) super.clone();
   }
 
   @Override
diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputMeta.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputMeta.java
index 7ef0d6c8e2..e90b3a9838 100644
--- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputMeta.java
+++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputMeta.java
@@ -356,35 +356,6 @@ public class TextFileOutputMeta extends BaseTransformMeta<TextFileOutput, TextFi
     setFileCompression(fileCompressionTypeCodes[FILE_COMPRESSION_TYPE_NONE]);
   }
 
-  public TextFileOutputMeta(TextFileOutputMeta m) {
-    this();
-    this.createParentFolder = m.createParentFolder;
-    this.enclosure = m.enclosure;
-    this.enclosureFixDisabled = m.enclosureFixDisabled;
-    this.enclosureForced = m.enclosureForced;
-    this.encoding = m.encoding;
-    this.endedLine = m.endedLine;
-    this.fileCompression = m.fileCompression;
-    this.fileFormat = m.fileFormat;
-    this.fileNameField = m.fileNameField;
-    this.fileNameInField = m.fileNameInField;
-    this.footerEnabled = m.footerEnabled;
-    this.headerEnabled = m.headerEnabled;
-    this.ignoreFields = m.ignoreFields;
-    this.schemaDefinition = m.schemaDefinition;
-    this.separator = m.separator;
-    this.fileSettings = new FileSettings(m.fileSettings);
-    m.outputFields.forEach(
-        field -> {
-          this.outputFields.add(new TextFileField(field));
-        });
-  }
-
-  @Override
-  public Object clone() {
-    return new TextFileOutputMeta(this);
-  }
-
   /**
    * @param varSpace for variable substitution
    * @return At how many rows to split into another file.
diff --git a/plugins/transforms/tika/src/main/java/org/apache/hop/pipeline/transforms/tika/TikaMeta.java b/plugins/transforms/tika/src/main/java/org/apache/hop/pipeline/transforms/tika/TikaMeta.java
index 56c17d3ff7..107f2815b3 100755
--- a/plugins/transforms/tika/src/main/java/org/apache/hop/pipeline/transforms/tika/TikaMeta.java
+++ b/plugins/transforms/tika/src/main/java/org/apache/hop/pipeline/transforms/tika/TikaMeta.java
@@ -172,37 +172,6 @@ public class TikaMeta extends BaseTransformMeta<Tika, TikaData> {
     this.filenameField = "filename";
   }
 
-  public TikaMeta(TikaMeta meta) {
-    this();
-    for (TikaFile file : meta.files) {
-      this.files.add(new TikaFile(file));
-    }
-    this.contentFieldName = meta.contentFieldName;
-    this.fileSizeFieldName = meta.fileSizeFieldName;
-    this.filenameField = meta.filenameField;
-    this.rowNumberField = meta.rowNumberField;
-    this.rowLimit = meta.rowLimit;
-    this.outputFormat = meta.outputFormat;
-    this.encoding = meta.encoding;
-    this.dynamicFilenameField = meta.dynamicFilenameField;
-    this.fileInField = meta.fileInField;
-    this.addingResultFile = meta.addingResultFile;
-    this.ignoreEmptyFile = meta.ignoreEmptyFile;
-    this.shortFileFieldName = meta.shortFileFieldName;
-    this.pathFieldName = meta.pathFieldName;
-    this.hiddenFieldName = meta.hiddenFieldName;
-    this.lastModificationTimeFieldName = meta.lastModificationTimeFieldName;
-    this.uriFieldName = meta.uriFieldName;
-    this.rootUriNameFieldName = meta.rootUriNameFieldName;
-    this.extensionFieldName = meta.extensionFieldName;
-    this.metadataFieldName = meta.metadataFieldName;
-  }
-
-  @Override
-  public TikaMeta clone() {
-    return new TikaMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta rowMeta,
diff --git a/plugins/transforms/tokenreplacement/src/main/java/org/apache/hop/pipeline/transforms/tokenreplacement/TokenReplacementMeta.java b/plugins/transforms/tokenreplacement/src/main/java/org/apache/hop/pipeline/transforms/tokenreplacement/TokenReplacementMeta.java
index ae49af7bf2..b49a89634e 100644
--- a/plugins/transforms/tokenreplacement/src/main/java/org/apache/hop/pipeline/transforms/tokenreplacement/TokenReplacementMeta.java
+++ b/plugins/transforms/tokenreplacement/src/main/java/org/apache/hop/pipeline/transforms/tokenreplacement/TokenReplacementMeta.java
@@ -275,37 +275,6 @@ public class TokenReplacementMeta
     tokenEndString = "}";
   }
 
-  public TokenReplacementMeta(TokenReplacementMeta m) {
-    this();
-    this.inputType = m.inputType;
-    this.inputText = m.inputText;
-    this.inputFieldName = m.inputFieldName;
-    this.inputFileName = m.inputFileName;
-    this.inputFileNameInField = m.inputFileNameInField;
-    this.inputFileNameField = m.inputFileNameField;
-    this.addInputFileNameToResult = m.addInputFileNameToResult;
-    this.outputType = m.outputType;
-    this.outputFieldName = m.outputFieldName;
-    this.outputFileName = m.outputFileName;
-    this.outputFileNameInField = m.outputFileNameInField;
-    this.outputFileNameField = m.outputFileNameField;
-    this.appendOutputFileName = m.appendOutputFileName;
-    this.createParentFolder = m.createParentFolder;
-    this.outputFileFormat = m.outputFileFormat;
-    this.outputFileEncoding = m.outputFileEncoding;
-    this.splitEvery = m.splitEvery;
-    this.includeTransformNrInOutputFileName = m.includeTransformNrInOutputFileName;
-    this.includePartNrInOutputFileName = m.includePartNrInOutputFileName;
-    this.includeDateInOutputFileName = m.includeDateInOutputFileName;
-    this.includeTimeInOutputFileName = m.includeTimeInOutputFileName;
-    this.specifyDateFormatOutputFileName = m.specifyDateFormatOutputFileName;
-    this.dateFormatOutputFileName = m.dateFormatOutputFileName;
-    this.addOutputFileNameToResult = m.addOutputFileNameToResult;
-    this.tokenStartString = m.tokenStartString;
-    this.tokenEndString = m.tokenEndString;
-    m.tokenReplacementFields.forEach(f -> tokenReplacementFields.add(new TokenReplacementField(f)));
-  }
-
   public String getOutputFileEncoding() {
     return Const.NVL(
         outputFileEncoding, Const.getEnvironmentVariable(CONST_FILE_ENCODING, Const.UTF_8));
@@ -320,11 +289,6 @@ public class TokenReplacementMeta
     };
   }
 
-  @Override
-  public Object clone() {
-    return new TokenReplacementMeta(this);
-  }
-
   public String buildFilename(
       String fileName, IVariables variables, int transformnr, String partnr, int splitnr) {
     return buildFilename(fileName, variables, transformnr, partnr, splitnr, this);
diff --git a/plugins/transforms/uniquerows/src/main/java/org/apache/hop/pipeline/transforms/uniquerows/UniqueRowsMeta.java b/plugins/transforms/uniquerows/src/main/java/org/apache/hop/pipeline/transforms/uniquerows/UniqueRowsMeta.java
index 5ae72e6eb4..2cc7841574 100644
--- a/plugins/transforms/uniquerows/src/main/java/org/apache/hop/pipeline/transforms/uniquerows/UniqueRowsMeta.java
+++ b/plugins/transforms/uniquerows/src/main/java/org/apache/hop/pipeline/transforms/uniquerows/UniqueRowsMeta.java
@@ -165,11 +165,6 @@ public class UniqueRowsMeta extends BaseTransformMeta<UniqueRows, UniqueRowsData
     this.errorDescription = errorDescription;
   }
 
-  @Override
-  public Object clone() {
-    return new UniqueRowsMeta(this);
-  }
-
   @Override
   public void setDefault() {
     countRows = false;
diff --git a/plugins/transforms/uniquerowsbyhashset/src/main/java/org/apache/hop/pipeline/transforms/uniquerowsbyhashset/UniqueRowsByHashSetMeta.java b/plugins/transforms/uniquerowsbyhashset/src/main/java/org/apache/hop/pipeline/transforms/uniquerowsbyhashset/UniqueRowsByHashSetMeta.java
index 4fa440610b..09c420b1bd 100644
--- a/plugins/transforms/uniquerowsbyhashset/src/main/java/org/apache/hop/pipeline/transforms/uniquerowsbyhashset/UniqueRowsByHashSetMeta.java
+++ b/plugins/transforms/uniquerowsbyhashset/src/main/java/org/apache/hop/pipeline/transforms/uniquerowsbyhashset/UniqueRowsByHashSetMeta.java
@@ -108,19 +108,6 @@ public class UniqueRowsByHashSetMeta
     storeValues = true;
   }
 
-  public UniqueRowsByHashSetMeta(UniqueRowsByHashSetMeta m) {
-    this();
-    this.storeValues = m.storeValues;
-    this.rejectDuplicateRow = m.rejectDuplicateRow;
-    this.errorDescription = m.errorDescription;
-    m.compareFields.forEach(f -> this.compareFields.add(new CompareField(f)));
-  }
-
-  @Override
-  public Object clone() {
-    return new UniqueRowsByHashSetMeta(this);
-  }
-
   @Override
   public void check(
       List<ICheckResult> remarks,
diff --git a/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateMeta.java b/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateMeta.java
index fef7a4c455..79ae398ae4 100644
--- a/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateMeta.java
+++ b/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateMeta.java
@@ -138,12 +138,6 @@ public class UpdateMeta extends BaseTransformMeta<Update, UpdateData> {
     lookupField = new UpdateLookupField();
   }
 
-  @Override
-  public Object clone() {
-    UpdateMeta retval = (UpdateMeta) super.clone();
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     skipLookup = false;
diff --git a/plugins/transforms/update/src/test/java/org/apache/hop/pipeline/transforms/update/UpdateChangeDetectionTest.java b/plugins/transforms/update/src/test/java/org/apache/hop/pipeline/transforms/update/UpdateChangeDetectionTest.java
new file mode 100644
index 0000000000..41b16f6f98
--- /dev/null
+++ b/plugins/transforms/update/src/test/java/org/apache/hop/pipeline/transforms/update/UpdateChangeDetectionTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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
+ *
+ *      http://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.hop.pipeline.transforms.update;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Reproduces issue #8022 for the Update transform: UpdateMeta.clone() is a shallow Object.clone()
+ * so the nested UpdateLookupField (schema, table, lookup keys, update fields) is shared with the
+ * "before" snapshot that HopGuiPipelineTransformDelegate compares against.
+ */
+class UpdateChangeDetectionTest {
+
+  @BeforeAll
+  static void setUpBeforeClass() throws Exception {
+    HopEnvironment.init();
+  }
+
+  private static TransformMeta updateTransform() {
+    UpdateMeta meta = new UpdateMeta();
+    meta.setConnection("db");
+    meta.setCommitSize("100");
+    meta.getLookupField().setSchemaName("public");
+    meta.getLookupField().setTableName("customers");
+    meta.getLookupField().getLookupKeys().add(new UpdateKeyField());
+
+    TransformMeta transformMeta = new TransformMeta("Update", meta);
+    transformMeta.setTransformPluginId("Update");
+    return transformMeta;
+  }
+
+  private static boolean delegateSeesChange(TransformMeta before, TransformMeta after)
+      throws Exception {
+    return !before.getXml().equals(after.getXml());
+  }
+
+  @Test
+  void changingTheTargetTableIsNotDetected() throws Exception {
+    TransformMeta transformMeta = updateTransform();
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    // UpdateDialog.getInfo(): setters on the *shared* nested lookup object.
+    UpdateMeta live = (UpdateMeta) transformMeta.getTransform();
+    live.getLookupField().setSchemaName("reporting");
+    live.getLookupField().setTableName("orders");
+    live.getLookupField().getLookupKeys().clear();
+
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+
+    System.out.println(
+        "nested lookup object shared with snapshot: "
+            + (((UpdateMeta) before.getTransform()).getLookupField() == live.getLookupField()));
+
+    assertTrue(delegateSeesChange(before, after), "changing schema/table/keys must be detected");
+  }
+
+  @Test
+  void changingTheCommitSizeIsDetected() throws Exception {
+    TransformMeta transformMeta = updateTransform();
+    TransformMeta before = (TransformMeta) transformMeta.clone();
+
+    ((UpdateMeta) transformMeta.getTransform()).setCommitSize("5000");
+
+    TransformMeta after = (TransformMeta) transformMeta.clone();
+
+    assertTrue(delegateSeesChange(before, after), "commit size is detected today");
+  }
+}
diff --git a/plugins/transforms/validator/src/main/java/org/apache/hop/pipeline/transforms/validator/ValidatorMeta.java b/plugins/transforms/validator/src/main/java/org/apache/hop/pipeline/transforms/validator/ValidatorMeta.java
index 73b7bc5af7..014b15a59c 100644
--- a/plugins/transforms/validator/src/main/java/org/apache/hop/pipeline/transforms/validator/ValidatorMeta.java
+++ b/plugins/transforms/validator/src/main/java/org/apache/hop/pipeline/transforms/validator/ValidatorMeta.java
@@ -116,21 +116,6 @@ public class ValidatorMeta extends BaseTransformMeta<Validator, ValidatorData> {
     this.validations = new ArrayList<>();
   }
 
-  public ValidatorMeta(ValidatorMeta m) {
-    this();
-    m.validations.forEach(v -> this.validations.add(new Validation(v)));
-    this.validatingAll = m.validatingAll;
-    this.concatenatingErrors = m.concatenatingErrors;
-    this.concatenationSeparator = m.concatenationSeparator;
-    this.suppressingLogFailedData = m.suppressingLogFailedData;
-    this.suppressingErrorLog = m.suppressingErrorLog;
-  }
-
-  @Override
-  public ValidatorMeta clone() {
-    return new ValidatorMeta(this);
-  }
-
   @Override
   public void check(
       List remarks,
diff --git a/plugins/transforms/validator/src/test/java/org/apache/hop/pipeline/transforms/validator/ValidatorMetaTest.java b/plugins/transforms/validator/src/test/java/org/apache/hop/pipeline/transforms/validator/ValidatorMetaTest.java
index c65f32fbca..ea9d388095 100644
--- a/plugins/transforms/validator/src/test/java/org/apache/hop/pipeline/transforms/validator/ValidatorMetaTest.java
+++ b/plugins/transforms/validator/src/test/java/org/apache/hop/pipeline/transforms/validator/ValidatorMetaTest.java
@@ -94,7 +94,7 @@ class ValidatorMetaTest {
     validation.setNullAllowed(false);
     meta.getValidations().add(validation);
 
-    ValidatorMeta clone = meta.clone();
+    ValidatorMeta clone = (ValidatorMeta) meta.clone();
     assertNotSame(meta, clone);
     assertNotSame(meta.getValidations(), clone.getValidations());
     assertNotSame(meta.getValidations().getFirst(), clone.getValidations().getFirst());
diff --git a/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMeta.java b/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMeta.java
index 508b339631..30961c55b2 100644
--- a/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMeta.java
+++ b/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMeta.java
@@ -136,34 +136,6 @@ public class WebServiceMeta extends BaseTransformMeta<WebService, WebServiceData
     fieldsOut = new ArrayList<>();
   }
 
-  public WebServiceMeta(WebServiceMeta m) {
-    this();
-    this.callTransform = m.callTransform;
-    this.compatible = m.compatible;
-    this.httpLogin = m.httpLogin;
-    this.httpPassword = m.httpPassword;
-    this.inFieldArgumentName = m.inFieldArgumentName;
-    this.inFieldContainerName = m.inFieldContainerName;
-    this.operationName = m.operationName;
-    this.operationNamespace = m.operationNamespace;
-    this.operationRequestName = m.operationRequestName;
-    this.outFieldArgumentName = m.outFieldArgumentName;
-    this.outFieldContainerName = m.outFieldContainerName;
-    this.passingInputData = m.passingInputData;
-    this.proxyHost = m.proxyHost;
-    this.proxyPort = m.proxyPort;
-    this.repeatingElementName = m.repeatingElementName;
-    this.returningReplyAsString = m.returningReplyAsString;
-    this.url = m.url;
-    m.fieldsIn.forEach(field -> fieldsIn.add(new WebServiceField(field)));
-    m.fieldsOut.forEach(field -> fieldsOut.add(new WebServiceField(field)));
-  }
-
-  @Override
-  public WebServiceMeta clone() {
-    return new WebServiceMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta r,
diff --git a/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogMeta.java b/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogMeta.java
index 32a13da9b3..f0c8e84dc8 100644
--- a/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogMeta.java
+++ b/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogMeta.java
@@ -94,13 +94,6 @@ public class WriteToLogMeta extends BaseTransformMeta<WriteToLog, WriteToLogData
     super();
   }
 
-  @Override
-  public Object clone() {
-    WriteToLogMeta retval = (WriteToLogMeta) super.clone();
-
-    return retval;
-  }
-
   /** Added for backwards compatibility with older prefixed log level values. */
   @Override
   public void convertLegacyXml(Node node) throws HopException {
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/addxml/AddXmlMeta.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/addxml/AddXmlMeta.java
index 9ad21bcb1b..0f7a0f531a 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/addxml/AddXmlMeta.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/addxml/AddXmlMeta.java
@@ -123,20 +123,6 @@ public class AddXmlMeta extends BaseTransformMeta<AddXml, AddXmlData> {
     outputFields = new ArrayList<>();
   }
 
-  public AddXmlMeta(AddXmlMeta m) {
-    this();
-    this.encoding = m.encoding;
-    this.omitDetails = new OmitDetails(m.omitDetails);
-    this.rootNode = m.rootNode;
-    this.valueName = m.valueName;
-    m.outputFields.forEach(f -> outputFields.add(new XmlField(f)));
-  }
-
-  @Override
-  public Object clone() {
-    return new AddXmlMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmlinputstream/XmlInputStreamMeta.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmlinputstream/XmlInputStreamMeta.java
index 03564ee166..b5f157068d 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmlinputstream/XmlInputStreamMeta.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmlinputstream/XmlInputStreamMeta.java
@@ -210,46 +210,6 @@ public class XmlInputStreamMeta extends BaseTransformMeta<XmlInputStream, XmlInp
     xmlDataValueField = "xml_data_value";
   }
 
-  public XmlInputStreamMeta(XmlInputStreamMeta m) {
-    this();
-    this.addResultFile = m.addResultFile;
-    this.defaultStringLen = m.defaultStringLen;
-    this.enableNamespaces = m.enableNamespaces;
-    this.enableTrim = m.enableTrim;
-    this.encoding = m.encoding;
-    this.filename = m.filename;
-    this.filenameField = m.filenameField;
-    this.includeFilenameField = m.includeFilenameField;
-    this.includeRowNumberField = m.includeRowNumberField;
-    this.includeXmlDataNameField = m.includeXmlDataNameField;
-    this.includeXmlDataTypeDescriptionField = m.includeXmlDataTypeDescriptionField;
-    this.includeXmlDataTypeNumericField = m.includeXmlDataTypeNumericField;
-    this.includeXmlDataValueField = m.includeXmlDataValueField;
-    this.includeXmlElementIDField = m.includeXmlElementIDField;
-    this.includeXmlElementLevelField = m.includeXmlElementLevelField;
-    this.includeXmlLocationColumnField = m.includeXmlLocationColumnField;
-    this.includeXmlLocationLineField = m.includeXmlLocationLineField;
-    this.includeXmlParentElementIDField = m.includeXmlParentElementIDField;
-    this.includeXmlParentPathField = m.includeXmlParentPathField;
-    this.includeXmlPathField = m.includeXmlPathField;
-    this.nrRowsToSkip = m.nrRowsToSkip;
-    this.rowLimit = m.rowLimit;
-    this.rowNumberField = m.rowNumberField;
-    this.sourceFieldName = m.sourceFieldName;
-    this.sourceFromInput = m.sourceFromInput;
-    this.xmlDataNameField = m.xmlDataNameField;
-    this.xmlDataTypeDescriptionField = m.xmlDataTypeDescriptionField;
-    this.xmlDataTypeNumericField = m.xmlDataTypeNumericField;
-    this.xmlDataValueField = m.xmlDataValueField;
-    this.xmlElementIDField = m.xmlElementIDField;
-    this.xmlElementLevelField = m.xmlElementLevelField;
-    this.xmlLocationColumnField = m.xmlLocationColumnField;
-    this.xmlLocationLineField = m.xmlLocationLineField;
-    this.xmlParentElementIDField = m.xmlParentElementIDField;
-    this.xmlParentPathField = m.xmlParentPathField;
-    this.xmlPathField = m.xmlPathField;
-  }
-
   @Override
   public void getFields(
       IRowMeta r,
@@ -351,11 +311,6 @@ public class XmlInputStreamMeta extends BaseTransformMeta<XmlInputStream, XmlInp
     }
   }
 
-  @Override
-  public Object clone() {
-    return new XmlInputStreamMeta(this);
-  }
-
   @Override
   public void check(
       List<ICheckResult> remarks,
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmljoin/XmlJoinMeta.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmljoin/XmlJoinMeta.java
index 97c2293bed..dd822b2866 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmljoin/XmlJoinMeta.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmljoin/XmlJoinMeta.java
@@ -107,26 +107,6 @@ public class XmlJoinMeta extends BaseTransformMeta<XmlJoin, XmlJoinData> {
     encoding = Const.UTF_8;
   }
 
-  public XmlJoinMeta(XmlJoinMeta m) {
-    this();
-    this.complexJoin = m.complexJoin;
-    this.encoding = m.encoding;
-    this.joinCompareField = m.joinCompareField;
-    this.omitNullValues = m.omitNullValues;
-    this.omitXmlHeader = m.omitXmlHeader;
-    this.sourceXmlField = m.sourceXmlField;
-    this.sourceXmlTransform = m.sourceXmlTransform;
-    this.targetXmlField = m.targetXmlField;
-    this.targetXmlTransform = m.targetXmlTransform;
-    this.targetXPath = m.targetXPath;
-    this.valueXmlField = m.valueXmlField;
-  }
-
-  @Override
-  public Object clone() {
-    return new XmlJoinMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta row,
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputMeta.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputMeta.java
index e1ca7c3058..11e63a1f27 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputMeta.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputMeta.java
@@ -221,21 +221,6 @@ public class XmlOutputMeta extends BaseTransformMeta<XmlOutput, XmlOutputData> {
     repeatElement = "Row";
   }
 
-  public XmlOutputMeta(XmlOutputMeta m) {
-    this();
-    this.encoding = m.encoding;
-    this.fileDetails = new FileDetails(m.fileDetails);
-    this.mainElement = m.mainElement;
-    this.nameSpace = m.nameSpace;
-    this.repeatElement = m.repeatElement;
-    m.outputFields.forEach(field -> outputFields.add(new XmlField(field)));
-  }
-
-  @Override
-  public Object clone() {
-    return new XmlOutputMeta(this);
-  }
-
   public String getNewLine(String formatCode) {
     String nl = System.lineSeparator();
     if (formatCode != null) {
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xsdvalidator/XsdValidatorMeta.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xsdvalidator/XsdValidatorMeta.java
index 1be6a3d842..37c051cdb1 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xsdvalidator/XsdValidatorMeta.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xsdvalidator/XsdValidatorMeta.java
@@ -119,27 +119,6 @@ public class XsdValidatorMeta extends BaseTransformMeta<XsdValidator, XsdValidat
                     ALLOW_EXTERNAL_ENTITIES_FOR_XSD_VALIDATION_DEFAULT));
   }
 
-  public XsdValidatorMeta(XsdValidatorMeta m) {
-    this();
-    this.addValidationMessage = m.addValidationMessage;
-    this.allowExternalEntities = m.allowExternalEntities;
-    this.ifXmlInvalid = m.ifXmlInvalid;
-    this.ifXmlValid = m.ifXmlValid;
-    this.outputStringField = m.outputStringField;
-    this.resultFieldName = m.resultFieldName;
-    this.validationMessageField = m.validationMessageField;
-    this.xmlSourceFile = m.xmlSourceFile;
-    this.xmlStream = m.xmlStream;
-    this.xsdDefinedField = m.xsdDefinedField;
-    this.xsdFilename = m.xsdFilename;
-    this.xsdSource = m.xsdSource;
-  }
-
-  @Override
-  public Object clone() {
-    return new XsdValidatorMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xslt/XsltMeta.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xslt/XsltMeta.java
index 007e0580df..9319572fe9 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xslt/XsltMeta.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xslt/XsltMeta.java
@@ -86,24 +86,6 @@ public class XsltMeta extends BaseTransformMeta<Xslt, XsltData> {
     parameters = new ArrayList<>();
   }
 
-  public XsltMeta(XsltMeta m) {
-    this();
-    this.fieldName = m.fieldName;
-    this.resultFieldName = m.resultFieldName;
-    this.xslFactory = m.xslFactory;
-    this.xslFieldIsAFile = m.xslFieldIsAFile;
-    this.xslFileField = m.xslFileField;
-    this.xslFileFieldUse = m.xslFileFieldUse;
-    this.xslFilename = m.xslFilename;
-    m.outputProperties.forEach(p -> this.outputProperties.add(new OutputProperty(p)));
-    m.parameters.forEach(p -> this.parameters.add(new Parameter(p)));
-  }
-
-  @Override
-  public Object clone() {
-    return new XsltMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta inputRowMeta,
diff --git a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMeta.java b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMeta.java
index 5ff1826815..309336547f 100644
--- a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMeta.java
+++ b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMeta.java
@@ -163,30 +163,6 @@ public class YamlInputMeta extends BaseTransformMeta<YamlInput, YamlInputData> {
     yamlField = "";
   }
 
-  public YamlInputMeta(YamlInputMeta m) {
-    this();
-    this.includeFilename = m.includeFilename;
-    this.filenameField = m.filenameField;
-    this.includeRowNumber = m.includeRowNumber;
-    this.rowNumberField = m.rowNumberField;
-    this.rowLimit = m.rowLimit;
-    this.encoding = m.encoding;
-    this.yamlField = m.yamlField;
-    this.inFields = m.inFields;
-    this.sourceFile = m.sourceFile;
-    this.addingResultFile = m.addingResultFile;
-    this.validating = m.validating;
-    this.ignoringEmptyFile = m.ignoringEmptyFile;
-    this.doNotFailIfNoFile = m.doNotFailIfNoFile;
-    m.yamlFiles.forEach(y -> this.yamlFiles.add(new YamlFile(y)));
-    m.inputFields.forEach(f -> this.inputFields.add(new YamlInputField(f)));
-  }
-
-  @Override
-  public YamlInputMeta clone() {
-    return new YamlInputMeta(this);
-  }
-
   @Override
   public void getFields(
       IRowMeta r,
diff --git a/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMetaTest.java b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMetaTest.java
index ee6c2c9789..40a129f060 100644
--- a/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMetaTest.java
+++ b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMetaTest.java
@@ -157,7 +157,7 @@ class YamlInputMetaTest {
     YamlInputField field = new YamlInputField("name");
     meta.getInputFields().add(field);
 
-    YamlInputMeta clone = meta.clone();
+    YamlInputMeta clone = (YamlInputMeta) meta.clone();
 
     assertNotSame(meta, clone);
 
diff --git a/plugins/transforms/zipfile/src/main/java/org/apache/hop/pipeline/transforms/zipfile/ZipFileMeta.java b/plugins/transforms/zipfile/src/main/java/org/apache/hop/pipeline/transforms/zipfile/ZipFileMeta.java
index df7df63423..a70f2f9c0e 100644
--- a/plugins/transforms/zipfile/src/main/java/org/apache/hop/pipeline/transforms/zipfile/ZipFileMeta.java
+++ b/plugins/transforms/zipfile/src/main/java/org/apache/hop/pipeline/transforms/zipfile/ZipFileMeta.java
@@ -234,13 +234,6 @@ public class ZipFileMeta extends BaseTransformMeta<ZipFile, ZipFileData> {
     this.operationType = operationType;
   }
 
-  @Override
-  public Object clone() {
-    ZipFileMeta retval = (ZipFileMeta) super.clone();
-
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     addResultFilenames = false;