[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Mutation

The new values of one task after a scheduling call. Each entry in [`ScheduleResult.updates`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md#updates>) is a `Mutation`. A date or leveling field holds a value only when the result reports that field; the others are `null`.

Which tasks get an entry is described on [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>). An entry belongs to a result that's read-only by contract, so call `deepClone()` before changing one.

## Declaration

```java
package org.dhtmlx.plen;

public class Mutation extends ValueRecord implements DeepCloneable<Mutation>
```

## Fields

The date and leveling fields have the same names and units as on [`TaskData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data.md#fields>). Each field has a fluent setter of the same name, `withX(value)`, that returns this entry.

| Field | Type | Set when | Description |
|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | always | Id of the task. |
| `kind` | [`MutationKind`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md#mutationkind>) | always | Whether the task is a leaf task, a summary or a milestone. |
| `startDate` | [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) | the start changed, or the task is reported in full | New start. |
| `endDate` | `Moment` | the end changed, or the task is reported in full | New end. |
| `duration` | `Double` | the duration changed, or the task is reported in full | New working time in the task's `durationUnit`. |
| `levelingDelay` | `Double` | the leveling delay changed | New leveling delay, as elapsed time in the task's `durationUnit`. |
| `pauses` | `Vec<`[`Pause`](<https://docs.dhtmlx.com/planning-engine/java/api/data/pause.md>)`>` | the pause list changed | The complete new pause list. An empty list when every pause was removed. A task that had no pauses and still has none never gets this field. |
| `reason` | [`Reason`](<https://docs.dhtmlx.com/planning-engine/java/api/results/reason.md>) | the call ran with `reasons = true` | What placed the task. |

A task is reported in full when `includeUnchanged` is set on [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md#includeunchanged>), or when a [`Project#apply`](<https://docs.dhtmlx.com/planning-engine/java/api/project-apply.md>) touched it since the last solve. Such an entry has `startDate`, `endDate` and `duration` all set, even if none of them changed.

## Methods

### deepClone

```java
public Mutation deepClone()
```

Returns a copy that has its own `pauses` list with cloned `Pause` entries. The copy shares the `reason` object with this entry.

**Returns**: a new `Mutation` with the same values.

### copy

```java
public Mutation copy()
```

Returns a shallow copy. The copy shares the `pauses` list and the `reason` object with this entry.

**Returns**: a new `Mutation` with the same field values.

### equals / hashCode / toString

Inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). `equals` and `hashCode` compare all public fields by value, with `pauses` compared element by element. `toString` returns a field dump, e.g. `Mutation{id=design, kind=TASK, …}`.

## Writing back

The field names match [`TaskUpdate`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/task-update.md>): each non-`null` value goes into the `TaskUpdate` field of the same name, wrapped in [`Patch.of(...)`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/patch.md#of>). `kind` and `reason` have no counterpart there.

```java
TaskUpdate update = new TaskUpdate(mutation.id);
if (mutation.startDate != null) update.withStartDate(Patch.of(mutation.startDate));
if (mutation.endDate != null) update.withEndDate(Patch.of(mutation.endDate));
if (mutation.duration != null) update.withDuration(Patch.of(mutation.duration));
if (mutation.levelingDelay != null) update.withLevelingDelay(Patch.of(mutation.levelingDelay));
if (mutation.pauses != null) update.withPauses(Patch.of(mutation.pauses));
```

## MutationKind

The kind of task an entry describes. It matches the task's [`TaskType`](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data.md#tasktype>) in the input data.

```java
package org.dhtmlx.plen;

public enum MutationKind { TASK, SUMMARY, MILESTONE }
```

| Value | Description |
|---|---|
| `TASK` | A leaf task (`TaskType.TASK`). The field default. |
| `SUMMARY` | A summary task (`TaskType.SUMMARY`). |
| `MILESTONE` | A milestone (`TaskType.MILESTONE`). |

## Example

```java
import java.util.List;
import org.dhtmlx.plen.*;

public class MutationExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 4, 6, 8, 0);

    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.str("design")).withStartDate(monday).withDuration(2.0),
            new TaskData(Id.str("build")).withStartDate(monday).withDuration(3.0)))
        .withLinks(List.of(
            new LinkData().withId(Id.str("l1"))
                .withSource(Id.str("design"))
                .withTarget(Id.str("build"))));

    ScheduleResult result = Engine.schedule(data, new SolveOptions().withReasons(true));

    for (Mutation update : result.updates) {
      if (update.startDate != null) {
        System.out.println(update.id + " (" + update.kind + ") starts " + update.startDate
            + ": " + update.reason);
      }
    }
  }
}
```

## Related

- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>) - the result that lists mutations
- [`Reason`](<https://docs.dhtmlx.com/planning-engine/java/api/results/reason.md>) - why a task was placed where it is
- [`TaskUpdate`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/task-update.md>) - writing a mutation back to a project
- [Reading results](<https://docs.dhtmlx.com/planning-engine/java/scheduling/reading-results.md#updates>) - reading updates from a result
- [Load all task dates](<https://docs.dhtmlx.com/planning-engine/java/how-to/load-all-task-dates.md>) - reporting every task with `includeUnchanged`
