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


# ResourceUpdate

An edit to one existing resource of a live project. It goes in the `update` list of [`SchedulingChanges.resources`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/scheduling-changes.md#resources>), which [`Project#apply`](<https://docs.dhtmlx.com/planning-engine/java/api/project-apply.md>) and [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/java/api/project-preview.md>) take. Create it with `new ResourceUpdate(id)` and set the fields to change with the fluent `withX` setters. To add a resource, put a [`ResourceData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/resource-data.md>) in `SchedulingChanges.resources.add` instead.

## Declaration

```java
package org.dhtmlx.plen;

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

## Constructors

### ResourceUpdate(Id)

```java
public ResourceUpdate(Id id)
```

Creates an update for the resource with the given id. `capacity` and `calendarId` start as [`Patch.missing()`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/patch.md#missing>), so the update changes nothing until one of them is set.

| Name | Type | Description |
|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | Id of the resource to edit, e.g. `Id.str("dev1")` or `Id.num(1)`. |

## Fields

All fields are public and mutable. `capacity` and `calendarId` are [`Patch<T>`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/patch.md>) values: `Patch.missing()` (the default) keeps the stored value, `Patch.of(value)` sets it, and `Patch.nullValue()` clears it. The **On `nullValue()`** column shows what clearing leaves behind. For the meaning of each value, see the field of the same name on [`ResourceData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/resource-data.md#fields>).

`Patch.of(null)` on either field stores `null`, the same as `Patch.nullValue()`.

| Field | Type | On `nullValue()` | Description |
|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | required | Id of the resource to edit. |
| `capacity` | `Patch<Double>` | `null`, so [`SchedulingConfig.defaultResourceCapacity`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#defaultresourcecapacity>) applies | New capacity, in assignment `value` units (`1.0` = 100 %). |
| `calendarId` | `Patch<Id>` | `null`, no calendar of its own | New working calendar of the resource. |

## Dates after an update

In [`CalendarMode.RESOURCE`](<https://docs.dhtmlx.com/planning-engine/java/api/data/calendar-mode.md>) with `useCalendars` on, a `calendarId` change can change the calendars that a leaf task's assignments work on. Each leaf task whose set of working calendars changes keeps its start and duration, and its end is derived again. In the `TASK` and `TASK_INHERITED` modes, the update doesn't move any dates. For how a resource calendar combines with a task calendar, see [Working-time calendars](<https://docs.dhtmlx.com/planning-engine/java/scheduling/working-time-calendars.md>).

## Methods

### withId, withCapacity, withCalendarId

```java
public ResourceUpdate withId(Id value)
public ResourceUpdate withCapacity(Patch<Double> value)
public ResourceUpdate withCalendarId(Patch<Id> value)
```

Each setter assigns its field and returns this instance.

**Returns** - this `ResourceUpdate`.

### deepClone

```java
public ResourceUpdate deepClone()
```

Returns a new `ResourceUpdate` with the same `id`, `capacity` and `calendarId`.

**Returns** - a new `ResourceUpdate`.

### copy

```java
public ResourceUpdate copy()
```

Returns a shallow copy of this instance.

**Returns** - a new `ResourceUpdate` with the same field values.

### equals, hashCode, toString

```java
public boolean equals(Object other)
public int hashCode()
public String toString()
```

Inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). Two updates are equal when `id`, `capacity` and `calendarId` are equal; patches compare by kind and carried value. `toString()` lists the fields, for logging; each patch shows only its kind.

## Errors

An update is rejected as a single operation, at path `resources.update[i]`. [`Project#apply`](<https://docs.dhtmlx.com/planning-engine/java/api/project-apply.md>) and [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/java/api/project-preview.md>) describe how a rejection is reported.

| Message | When it occurs |
|---|---|
| `unknown resource id` | No resource has `id`. |
| a validation message | The edited resource breaks a [`ResourceData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/resource-data.md#validation>) rule: `capacity` is negative, `NaN` or infinite, or, in [`CalendarMode.RESOURCE`](<https://docs.dhtmlx.com/planning-engine/java/api/data/calendar-mode.md>), `calendarId` names no calendar. |

## Example

Double a resource's capacity and drop its own calendar:

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

public class ResourceUpdateExample {
  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(2.0)))
        .withResources(List.of(
            new ResourceData().withId(Id.str("dev1")).withCapacity(1.0)))
        .withAssignments(List.of(
            new AssignmentData().withTask(Id.str("design")).withResource(Id.str("dev1")).withValue(1.0),
            new AssignmentData().withTask(Id.str("build")).withResource(Id.str("dev1")).withValue(1.0)));

    Project project = new Project();
    project.solve(data, new SolveOptions());

    SchedulingChanges changes = new SchedulingChanges();
    changes.resources.update.add(new ResourceUpdate(Id.str("dev1"))
        .withCapacity(Patch.of(2.0))
        .withCalendarId(Patch.nullValue()));

    ApplyReport report = project.apply(changes);
    if (report.rejected.isEmpty()) {
      ScheduleResult result = project.solve(null, new SolveOptions());
      int overallocated = result.overallocations == null ? 0 : result.overallocations.size();
      System.out.println("Overallocated resources: " + overallocated);
    }
  }
}
```

## Related

- [`ResourceData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/resource-data.md>) - the stored record and its rules
- [`Patch<T>`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/patch.md>) - the three-state type of `capacity` and `calendarId`
- [`SchedulingChanges`](<https://docs.dhtmlx.com/planning-engine/java/api/changes/scheduling-changes.md#resources>) - the change set that carries the update
- [Resources and assignments](<https://docs.dhtmlx.com/planning-engine/java/resources-and-assignment/resources-and-assignments.md#resources-and-capacity>) - resource capacity
- [Data Updates](<https://docs.dhtmlx.com/planning-engine/java/live-projects/editing-a-project.md#update-records-and-patch>) - update records in a live project
