# How to Define Relationships Between Datasets in Apache OSSIE

> Learn how Apache OSSIE defines dataset relationships using Relationship objects in the semantic model. Discover how join columns and parsing ensure seamless data integration with platforms like Salesforce.

- Repository: [The Apache Software Foundation/ossie](https://github.com/apache/ossie)
- Tags: how-to-guide
- Published: 2026-07-24

---

**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`](https://github.com/apache/ossie/blob/main/OsiModel.java) ([source](https://github.com/apache/ossie/blob/main/converters/polaris/src/main/java/org/apache/ossie/converter/polaris/model/OsiModel.java)), 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](https://github.com/apache/ossie/blob/main/converters/polaris/src/main/java/org/apache/ossie/converter/polaris/OsiModelParser.java)) reads this array and instantiates `Relationship` objects for each entry.

```yaml
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:

```java
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](https://github.com/apache/ossie/blob/main/converters/salesforce/src/main/java/org/apache/ossie/converter/RelationshipMappingHandler.java)) 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:

```java
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`](https://github.com/apache/ossie/blob/main/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.