Implementation:Datahub project Datahub ReadOnlyEntityException
| Knowledge Sources | |
|---|---|
| Domains | Java_SDK, Metadata_Management |
| Last Updated | 2026-02-10 00:00 GMT |
Overview
Description
ReadOnlyEntityException is an exception thrown when attempting to mutate a read-only entity. It extends UnsupportedOperationException and enforces immutability for entities fetched from the server. After fetching an entity via client.entities().get(), all mutation operations (set*(), add*(), remove*()) will throw this exception.
This immutability-by-default pattern:
- Makes mutations explicit and intentional
- Prevents accidental modification of fetched entities
- Enables safe passing of entities to functions without risk of mutation
- Provides a clear separation between read and write workflows
The exception generates a detailed error message with two resolution strategies and code examples specific to the entity type and operation.
Usage
This exception is thrown internally by the entity framework when a mutation method is called on a read-only entity. Users should call entity.mutable() to obtain a mutable copy before performing mutations, or use a builder to create new mutable entities.
Code Reference
Source Location
metadata-integration/java/datahub-client/src/main/java/datahub/client/v2/exceptions/ReadOnlyEntityException.java
Signature
public class ReadOnlyEntityException extends UnsupportedOperationException {
public ReadOnlyEntityException(@Nonnull String entityType, @Nonnull String operation)
@Nonnull
public String getEntityType()
@Nonnull
public String getOperation()
}
Import
import datahub.client.v2.exceptions.ReadOnlyEntityException;
I/O Contract
Inputs
| Parameter | Type | Description |
|---|---|---|
entityType |
String |
The type of entity (e.g., "chart", "dataset") |
operation |
String |
The mutation operation that was attempted (e.g., "set description", "add tag") |
Outputs
| Method | Return Type | Description |
|---|---|---|
| getEntityType | String |
The entity type on which the mutation was attempted |
| getOperation | String |
The mutation operation that was attempted |
| getMessage | String |
Detailed error message with two resolution strategies and code examples |
Usage Examples
// This exception is thrown automatically by the entity framework:
Dataset dataset = client.entities().get(urn); // Read-only entity
dataset.setDescription("Updated"); // Throws ReadOnlyEntityException!
// Resolution 1: Create a mutable copy (recommended for fetched entities)
Dataset dataset = client.entities().get(urn); // Read-only
String desc = dataset.getDescription(); // Reads work fine
Dataset mutable = dataset.mutable(); // Get mutable copy
mutable.setDescription("Updated"); // Now mutations work
client.entities().upsert(mutable);
// Resolution 2: Use builder for new entities (already mutable)
Dataset dataset = Dataset.builder()
.platform("snowflake")
.name("table")
.build();
dataset.setDescription("New description"); // Works - builder entities are mutable
client.entities().upsert(dataset);
// Catching the exception
try {
fetchedEntity.setDescription("test");
} catch (ReadOnlyEntityException e) {
System.err.println("Entity type: " + e.getEntityType());
System.err.println("Operation: " + e.getOperation());
}
Related Pages
- Implementation:Datahub_project_Datahub_PendingMutationsException - Complementary exception for reads on dirty entities
- Implementation:Datahub_project_Datahub_DataHubClientException - Base exception class for the SDK
- Implementation:Datahub_project_Datahub_HasDomains_Mixin - Example mixin using
@RequiresMutableannotation