Implementation:Datahub project Datahub PendingMutationsException
| Knowledge Sources | |
|---|---|
| Domains | Java_SDK, Metadata_Management |
| Last Updated | 2026-02-10 00:00 GMT |
Overview
Description
PendingMutationsException is an exception thrown when attempting to read from an entity that has pending (unsaved) mutations. It extends ConcurrentModificationException and enforces a strict contract: after mutating an entity (via add*(), set*(), remove*() methods), reads are not allowed until the entity has been saved to the server.
This restriction exists to:
- Prevent reading potentially stale or incomplete cached data
- Force an explicit save-then-fetch workflow for data consistency
- Catch bugs where developers assume local mutations are immediately readable
The exception generates a detailed, actionable error message that includes three resolution strategies with code examples specific to the entity type and operation.
Usage
This exception is thrown internally by the entity framework when a read method is called on a dirty entity. Users should not instantiate this exception directly. Instead, they should follow one of the three resolution patterns described in the error message: save first, read before mutating, or separate mutation and read operations.
Code Reference
Source Location
metadata-integration/java/datahub-client/src/main/java/datahub/client/v2/exceptions/PendingMutationsException.java
Signature
public class PendingMutationsException extends ConcurrentModificationException {
public PendingMutationsException(@Nonnull String entityType, @Nonnull String operation)
@Nonnull
public String getEntityType()
@Nonnull
public String getOperation()
}
Import
import datahub.client.v2.exceptions.PendingMutationsException;
I/O Contract
Inputs
| Parameter | Type | Description |
|---|---|---|
entityType |
String |
The type of entity (e.g., "chart", "dataset") |
operation |
String |
The read operation that was attempted (e.g., "read chartType", "read tags") |
Outputs
| Method | Return Type | Description |
|---|---|---|
| getEntityType | String |
The entity type on which the read was attempted |
| getOperation | String |
The read operation that was attempted |
| getMessage | String |
Detailed error message with three resolution strategies and code examples |
Usage Examples
// This exception is thrown automatically by the entity framework:
Chart chart = Chart.builder().tool("looker").id("my_chart").build();
chart.setChartType("BAR"); // Mutation marks entity as dirty
String type = chart.getChartType(); // Throws PendingMutationsException!
// Resolution 1: Save entity first, then read
Chart chart = Chart.builder().tool("looker").id("my_chart").build();
chart.setChartType("BAR");
client.entities().upsert(chart); // Clears dirty flag
String type = chart.getChartType(); // Now works
// Resolution 2: Read before mutating
Chart chart = client.entities().get(chartUrn);
String existingType = chart.getChartType(); // Read first
if (existingType == null) {
chart.setChartType("BAR"); // Then mutate
client.entities().upsert(chart);
}
// Resolution 3: Separate mutation and read operations
Chart chart = Chart.builder().tool("looker").id("my_chart").build();
chart.setChartType("BAR");
client.entities().upsert(chart);
Chart fetched = client.entities().get(chartUrn);
String type = fetched.getChartType(); // Safe
Related Pages
- Datahub_project_Datahub_ReadOnlyEntityException - Complementary exception for mutations on read-only entities
- Datahub_project_Datahub_DataHubClientException - Base exception class for the SDK
- Datahub_project_Datahub_WriteTrackingAspectCache - Cache with dirty tracking that triggers this exception