🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Deepclone
This page was created by Lars.olofsson on 2017-05-20. Last edited by Wikiadmin on 2026-07-29.

You can create a new revision or working copy of an object graph by calling deepclone with a ViewModel that defines exactly which values and related objects to copy.

What deepclone does

Deepclone is an OCL operator that creates a new instance of the same class as its source object. The ViewModel supplied to the operator is the clone definition: its columns decide which attributes and association ends participate, and nested ViewModels decide which related objects are created as new objects.

The returned object is new and unsaved, and is included in the DirtyList.

self.deepclone('Person_DeepClone')

In this example, self is a Person. The expression returns a new Person created according to the ViewModel named Person_DeepClone.

Use deepclone for revisions

Use deepclone when a user needs a new object that starts with values from an existing object but can then be changed independently. Typical cases include revisions, copied templates, and detailed business objects with child records.

For example, a Thing has attributes Name, Number, and Description, plus a collection of Details. A clone definition can copy Name and Description, leave Number unset for the new revision, and create new Detail objects from the original details.

Define the clone ViewModel

Create a ViewModel rooted in the same class as the object you will clone. Treat this ViewModel as a technical template: it describes the output object graph rather than a screen that a user must see.

  1. Create a ViewModel with the root class, for example Person.
  2. Give the ViewModel a stable name, for example Person_DeepClone.
  3. Add columns for every root attribute that the clone must receive.
  4. For an association whose related objects must be newly created, add the association column and attach a nested ViewModel for the associated class.
  5. In each nested ViewModel, add the attributes to copy and further nested ViewModels for any deeper objects that must also be created.
  6. Set the ViewModel's DuckType class to the same class as the root. This helps you discover invalid column names after a model property is renamed.

The ViewModel can also calculate a value instead of copying it unchanged. For example, an expression for a copied name can append text to the original value:

self.Name + ' new'

Use this approach when the new revision needs a changed name or other derived initial value. Leave a column out when its value must not be copied, such as a revision number that users or other logic will assign later.

Decide how each association is handled

An association column can either cause deepclone to create related objects or retain references to existing related objects. The presence of a nested ViewModel is the key distinction.

ViewModel definition Result in the clone Example
Attribute column The new root object receives the column's evaluated value. Copy Person.Name to the new Person.
Association column with a nested ViewModel New associated object or objects are created according to the nested ViewModel and linked to the clone. A nested ResidentialBuilding ViewModel on Home creates a new Home for the new Person.
Association column without a nested ViewModel The clone receives a reference to the existing associated object or objects; no related objects are created. The new Person refers to the existing OwnedBuildings.

Cardinality can move an existing link

Retaining a reference is not always the same as sharing an object. Check the association cardinalities before you choose this option.

For example, if an OwnedBuilding can be linked to only one Person, assigning that existing building to the cloned Person moves the link. The building is no longer linked to the original Person; it is linked to the new one. If both people must retain buildings independently, define a nested ViewModel so that deepclone creates new building objects instead.

Make this decision for every association in the clone definition. Do not assume that an association without a nested ViewModel is harmless to the original object graph.

Call deepclone from a method or action

A class method makes the cloning operation reusable and gives the action a clear business name. For example, define a method on Person that returns Person and evaluates:

self.deepclone('Person_DeepClone')

You can then call the method from a class action and use its returned object as the root object for the ViewModel that the action opens. This keeps the action focused on opening the new revision while the clone definition remains in one named ViewModel.

Validate the result

Before using a clone definition in a revision workflow, test it with an object that has distinctive values at every level.

  1. Create a source object with recognizable root values and related objects.
  2. Run the deepclone expression or the method that wraps it.
  3. Confirm that expected root attributes were copied and intentionally omitted attributes were not copied.
  4. Confirm that associations with nested ViewModels contain new related objects.
  5. Confirm that associations without nested ViewModels still point to the intended existing objects.
  6. Check single-valued and otherwise restrictive associations on the original object to ensure that retaining a reference did not move a link unexpectedly.
  7. Save only after the cloned object graph has the intended values and links.

Relationship to transform

Deepclone is a special case of transform where the source and target class are the same. Use deepclone when you always need a new object of the same class. Use transform when the target needs to be a different type or when the transformation scenario requires that operator's capabilities.

See also