Implementation:Datahub project Datahub MetadataChangeProposalWrapper Builder
| Property | Value |
|---|---|
| Implementation Name | MetadataChangeProposalWrapper_Builder |
| Type | API Doc |
| Category | Java_SDK_Metadata_Emission |
| Workflow | Java_SDK_Metadata_Emission |
| Repository | https://github.com/datahub-project/datahub |
| Last Updated | 2026-02-09 17:00 GMT |
Overview
Description
MetadataChangeProposalWrapper_Builder documents the step builder API for constructing MetadataChangeProposalWrapper objects, which represent atomic metadata change proposals in the DataHub Java SDK. The builder enforces a mandatory construction sequence through a chain of typed interfaces: EntityTypeStepBuilder, EntityUrnStepBuilder, ChangeStepBuilder, AspectStepBuilder, and Build. Each step returns the next interface in the chain, guiding the developer through a validated construction flow that ensures all required fields are present before the wrapper is finalized.
The class also provides a create(Consumer<EntityTypeStepBuilder>) convenience factory that accepts a lambda for inline construction.
Usage
Use MetadataChangeProposalWrapper.builder() to start the step builder chain. Call entityType(), entityUrn(), upsert(), and aspect() in sequence, then call build() to produce the immutable wrapper. The aspect name is automatically inferred from the PDL schema of the provided aspect object; use aspectName() to override the inferred name when necessary.
Code Reference
Source Location
| Property | Value |
|---|---|
| File | metadata-integration/java/datahub-event/src/main/java/datahub/event/MetadataChangeProposalWrapper.java
|
| Lines | L23-150 |
| Repository | https://github.com/datahub-project/datahub |
Signature
Step builder entry point:
public static EntityTypeStepBuilder builder()
Lambda-based factory:
public static MetadataChangeProposalWrapper create(
Consumer<EntityTypeStepBuilder> builderConsumer
)
Step builder interface chain:
// Step 1: Set entity type
public interface EntityTypeStepBuilder {
EntityUrnStepBuilder entityType(String entityType);
}
// Step 2: Set entity URN
public interface EntityUrnStepBuilder {
ChangeStepBuilder entityUrn(String entityUrn);
ChangeStepBuilder entityUrn(Urn entityUrn);
}
// Step 3: Set change type
public interface ChangeStepBuilder {
AspectStepBuilder upsert();
}
// Step 4: Set aspect payload
public interface AspectStepBuilder {
Build aspect(DataTemplate aspect);
}
// Step 5: Build (with optional aspect name override)
public interface Build {
MetadataChangeProposalWrapper build();
Build aspectName(String aspectName);
}
Import
import datahub.event.MetadataChangeProposalWrapper;
import com.linkedin.data.template.DataTemplate;
import com.linkedin.common.urn.Urn;
import com.linkedin.events.metadata.ChangeType;
Key Fields
| Field | Type | Required | Description |
|---|---|---|---|
| entityType | String | Yes | The entity type identifier (e.g., "dataset", "dashboard", "chart", "dataJob")
|
| entityUrn | String or Urn | Yes | The globally unique URN of the target entity (e.g., "urn:li:dataset:(urn:li:dataPlatform:bigquery,my-project.my-dataset.table,PROD)"). Validated during construction via Urn.createFromString().
|
| changeType | ChangeType | Yes (set by upsert()) |
The type of mutation. Currently only ChangeType.UPSERT is supported through the step builder.
|
| aspect | DataTemplate | Yes | The typed metadata payload (e.g., DatasetProperties, SchemaMetadata, Ownership). Must extend com.linkedin.data.template.DataTemplate.
|
| aspectName | String | Auto-inferred (optional override) | The canonical name of the aspect. Automatically inferred from the PDL schema Aspect annotation on the provided DataTemplate. Can be explicitly set via aspectName() if inference fails.
|
I/O Contract
| Direction | Description |
|---|---|
| Input | Entity type string, entity URN string or Urn object, change type selection (upsert()), and a typed aspect object extending DataTemplate
|
| Output | An immutable MetadataChangeProposalWrapper<T> instance containing all fields, ready to be passed to Emitter.emit()
|
| Exceptions | EventValidationException if the URN is malformed, the aspect name cannot be inferred, or any required field is null. NullPointerException if entityType or entityUrn is null.
|
Usage Examples
Example 1: Basic dataset properties MCP
import com.linkedin.dataset.DatasetProperties;
import datahub.event.MetadataChangeProposalWrapper;
MetadataChangeProposalWrapper mcpw = MetadataChangeProposalWrapper.builder()
.entityType("dataset")
.entityUrn("urn:li:dataset:(urn:li:dataPlatform:bigquery,my-project.my-dataset.user-table,PROD)")
.upsert()
.aspect(new DatasetProperties().setDescription("Canonical User profile dataset"))
.build();
Example 2: Using Urn object instead of string
import com.linkedin.common.urn.Urn;
import com.linkedin.dataset.DatasetProperties;
import datahub.event.MetadataChangeProposalWrapper;
Urn datasetUrn = Urn.createFromString(
"urn:li:dataset:(urn:li:dataPlatform:mysql,db.users,PROD)"
);
MetadataChangeProposalWrapper mcpw = MetadataChangeProposalWrapper.builder()
.entityType("dataset")
.entityUrn(datasetUrn)
.upsert()
.aspect(new DatasetProperties().setDescription("Users table"))
.build();
Example 3: Explicit aspect name override
import datahub.event.MetadataChangeProposalWrapper;
MetadataChangeProposalWrapper mcpw = MetadataChangeProposalWrapper.builder()
.entityType("dataset")
.entityUrn("urn:li:dataset:(urn:li:dataPlatform:hive,warehouse.events,PROD)")
.upsert()
.aspect(myCustomAspect)
.aspectName("customAspectName")
.build();
Example 4: Lambda-based factory method
import datahub.event.MetadataChangeProposalWrapper;
import com.linkedin.dataset.DatasetProperties;
MetadataChangeProposalWrapper mcpw = MetadataChangeProposalWrapper.create(b ->
b.entityType("dataset")
.entityUrn("urn:li:dataset:(urn:li:dataPlatform:postgres,db.orders,PROD)")
.upsert()
.aspect(new DatasetProperties().setDescription("Orders fact table"))
);