How to Define Relationships Between Datasets in Apache OSSIE

In Apache OSSIE, relationships between datasets are defined within the semantic model as Relationship objects that specify source and target tables along with their join columns, parsed by OsiModelParser and converted by RelationshipMappingHandler for target platforms like Salesforce.

Apache OSSIE is an open-source data conversion framework that enables seamless mapping between diverse data sources. Understanding how relationships are defined between datasets is crucial for maintaining referential integrity when converting semantic models across platforms. This guide examines the core mechanisms OSSIE uses to declare, validate, and process dataset relationships according to the actual source implementation.

Relationship Structure in the Semantic Model

In OSSIE, relationship metadata resides in the OsiModel class as a list of Relationship objects under the relationships field. Each Relationship instance defines a directed link between two datasets using five key properties:

  • name: Human-readable identifier (e.g., customers_orders)
  • from: Source dataset name (the parent table)
  • to: Target dataset name (the child table)
  • from_columns: Column names in the source participating in the join
  • to_columns: Column names in the target participating in the join

The Relationship class is defined as an inner class within OsiModel.java (source), establishing the core data structure used throughout the conversion pipeline.

Declaring Relationships in YAML or JSON

Relationships are declared declaratively in your model configuration files under the top-level relationships key. When OSSIE parses the model, OsiModelParser (implementation) reads this array and instantiates Relationship objects for each entry.

datasets:
  - name: customers
    source: mysql
    fields:
      - name: id
        description: Customer primary key
  - name: orders
    source: mysql
    fields:
      - name: id
        description: Order primary key
      - name: customer_id
        description: FK to customers.id

relationships:
  - name: customers_orders
    from: customers
    to: orders
    from_columns: [id]
    to_columns: [customer_id]

This declarative approach allows data engineers to define complex join conditions between tables without writing additional code.

Creating Relationships Programmatically

For dynamic model generation, instantiate Relationship objects directly and attach them to an OsiModel instance:

import org.apache.ossie.converter.polaris.model.OsiModel;
import org.apache.ossie.converter.polaris.model.OsiModel.Relationship;

// Build the model
OsiModel model = new OsiModel();

// Define a relationship
Relationship rel = new Relationship();
rel.setName("customers_orders");
rel.setFrom("customers");
rel.setTo("orders");
rel.setFromColumns(List.of("id"));
rel.setToColumns(List.of("customer_id"));

// Attach it to the model
model.setRelationships(List.of(rel));

The programmatic approach is essential when building models from external metadata sources or when relationships must be constructed at runtime based on user input.

Validation and Target Conversion

OSSIE validates relationship definitions during the parsing phase. The RelationshipMappingHandler (source) filters out relationships referencing non-existent datasets or columns, ensuring only valid semantic relationships reach the target converter.

When converting to Salesforce, the handler transforms OSSIE relationships into semanticRelationships payloads:

import org.apache.ossie.converter.RelationshipMappingHandler;
import org.apache.ossie.converter.ConverterConstants;

// Assume model is populated
Map<String, Object> osiData = OsiModelParser.toMap(model);
RelationshipMappingHandler handler = new RelationshipMappingHandler();

Map<String, Object> sfPayload = handler.handle(
    osiData,
    ConverterConstants.Direction.OSI_TO_SF
);

The from and to fields map directly to the target platform's relationship structure, while validation logic ensures referential integrity before conversion.

Summary

  • Semantic Model Storage: Relationships are stored as Relationship objects within OsiModel.relationships in OsiModel.java.
  • Declarative Definition: Define relationships in YAML/JSON under the relationships key with name, from, to, from_columns, and to_columns.
  • Parsing: OsiModelParser deserializes relationship definitions and performs initial validation.
  • Programmatic Control: Create relationships dynamically using the Relationship class setters before attaching to the model.
  • Target Conversion: RelationshipMappingHandler validates relationships and converts them to platform-specific formats like Salesforce's semanticRelationships.

Frequently Asked Questions

What file format does OSSIE use to define relationships between datasets?

OSSIE accepts both YAML and JSON formats for model definitions. The OsiModelParser handles deserialization of the relationships array from either format into Java Relationship objects.

How does OSSIE validate that a relationship between datasets is valid?

During parsing, RelationshipMappingHandler validates that both the from and to datasets exist in the model and that the specified from_columns and to_columns are present in their respective tables. Invalid relationships are filtered out before conversion.

Can relationships be defined between datasets from different sources?

Yes, the source property on datasets indicates their origin (e.g., MySQL, PostgreSQL), while relationships define the semantic linkage independent of the underlying source. The relationship structure only requires matching column values between the parent and child datasets.

What happens to relationship definitions when converting to Salesforce?

The RelationshipMappingHandler maps OSSIE relationship properties to Salesforce's semanticRelationships format. The from dataset becomes the parent object, to becomes the child, and the column mappings define the foreign key relationships in the target platform.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →