You can use the deepclone OCL operator when you need a new, unsaved instance of the same class with attributes and relationships copied according to a ViewModel.
What deepclone does
deepclone creates a new object of the same class as its source object. The new object is unsaved and is included in the DirtyList.
The ViewModel named in the expression defines the clone structure:
- Attributes included in the ViewModel are copied to the new object.
- An association column with a nested ViewModel creates cloned associated object or objects according to that nested definition.
- An association column without a nested ViewModel retains a reference to the existing associated object or objects; it does not create copies of them.
This makes deepclone suitable for scenarios such as creating a new revision from an existing object structure, then changing selected values on the new revision.
Syntax
object.deepclone('ViewModelName')| Part | Meaning |
|---|---|
object
|
The source object to copy. |
deepclone
|
Creates a new instance of the same class as the source. |
'ViewModelName'
|
The name of the ViewModel that defines which attributes and association paths are copied or retained as references. |
Example
The following expression takes the first available Customer and creates a new Customer according to the Customer ViewModel:
Customer.allinstances->first.deepclone('Customer')The result is the new Customer, not the original object. What the new customer contains depends entirely on the Customer ViewModel.
Define the clone with a ViewModel
Configure a ViewModel specifically for the clone operation rather than assuming that every association should be copied. For each attribute and association that the clone needs:
- Add the root class and the required attributes to the ViewModel.
- Add each association that the clone should contain.
- Attach a nested ViewModel to an association when its related object or objects must be created as new copies.
- Leave an association without a nested ViewModel when the new root object should retain links to the existing related object or objects.
- Set the ViewModel's DuckType class to the same class as the root class.
Setting the DuckType class helps reveal incorrectly named ViewModel columns. This is important after renaming a model attribute: a clone ViewModel may otherwise still contain the old attribute name.
Association example
Consider a Person clone ViewModel that includes Home and OwnedBuildings:
- If the
Homecolumn has a nestedResidentialBuildingViewModel, deepclone creates a newHomeobject and links it to the newPerson. - If the
OwnedBuildingscolumn has no nested ViewModel, deepclone links the existingOwnedBuildingsobjects to the newPersonrather than creating new building objects.
Check the association cardinality before retaining references. If an existing related object can be linked to only one Person, linking that object to the new clone removes the link from the original Person. In the example, the existing OwnedBuildings become available through the new person and no longer through the original person.
Use deepclone from a method
A useful pattern is to place the cloning expression in a method on the root class. For example, define a method such as CreateClone() : Person that returns:
self.deepclone('Person_DeepClone')You can then call self.CreateClone from a class action and use the returned object as the root of the ViewModel opened by that action.
Deepclone and transform
deepclone is a special case of transform: it uses the same class for both source and target and always creates the destination object. You do not provide a destination object for deepclone.
Use deepclone when the copy must remain the same class as the source. Use transform when the target may be a different type or when you need the broader transform behavior.
Checklist
Before using deepclone, verify that:
- The named ViewModel exists and has the source class as its root and DuckType class.
- Every attribute that must be copied is included in the ViewModel.
- Every association is deliberately configured either with a nested ViewModel to create copies or without one to retain existing references.
- Association cardinalities allow retained references without unexpectedly moving a relationship from the original object.
- The calling logic uses the returned new object, because the source object is not replaced.
