# How to Define Relationships Between Datasets in Ossie: YAML and Java Guide

> Learn how to define relationships between datasets in Ossie using YAML or Java. Declare relationships in the semantic model or construct them via the OsiModel API for seamless data integration.

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

---

**To define relationships between datasets in Ossie, declare them in the semantic model's `relationships` array with `name`, `from`, `to`, `from_columns`, and `to_columns` properties, or construct `Relationship` objects programmatically via the `OsiModel` API.**

Apache Ossie (Open Source Semantic Interchange Engine) manages dataset metadata through a semantic model that supports linking tables via foreign-key-style relationships. When you define relationships between datasets in Ossie, you create joinable connections that conversion tools use to generate target-specific payloads like Salesforce `semanticRelationships`. These relationships are stored as `Relationship` instances within the `OsiModel` class and parsed by `OsiModelParser` from YAML or JSON definitions.

## Understanding Ossie Relationship Metadata

In Ossie, a **relationship** describes how two datasets (tables) are linked together. The relationship metadata lives in the semantic model (`OsiModel`) and is exposed as a list of `Relationship` objects under the `relationships` field.

According to the source code in [`converters/polaris/src/main/java/org/apache/ossie/converter/polaris/model/OsiModel.java`](https://github.com/apache/ossie/blob/main/converters/polaris/src/main/java/org/apache/ossie/converter/polaris/model/OsiModel.java), the `Relationship` inner class contains the following properties:

- **`name`**: Human-readable identifier for the relationship (e.g., `customers_orders`)
- **`from`**: The source dataset name (the "parent" side)
- **`to`**: The target dataset name (the "child" side)
- **`from_columns`**: List of column names in the source dataset that participate in the join
- **`to_columns`**: List of column names in the target dataset that participate in the join

When Ossie parses a model, the `OsiModelParser` class reads the `relationships` array and creates a `Relationship` instance for each entry.

## Method 1: Define Relationships in YAML

The simplest way to define relationships between datasets in Ossie is to declare them in your model file under the top-level `relationships` key. The `OsiModelParser` located at [`converters/polaris/src/main/java/org/apache/ossie/converter/polaris/OsiModelParser.java`](https://github.com/apache/ossie/blob/main/converters/polaris/src/main/java/org/apache/ossie/converter/polaris/OsiModelParser.java) deserializes this array into Java objects.

```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 YAML structure maps directly to the `Relationship` class properties. The `from` and `to` fields reference dataset names defined in the `datasets` section, while `from_columns` and `to_columns` specify the join keys.

## Method 2: Define Relationships Programmatically

You can also manipulate relationships programmatically by creating or updating `Relationship` objects on an `OsiModel` instance. This approach is useful when building models dynamically or integrating Ossie into a larger data pipeline.

```java
import org.apache.ossie.converter.polaris.model.OsiModel;
import org.apache.ossie.converter.polaris.model.OsiModel.Relationship;
import java.util.List;

// 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 `OsiModel` class acts as the container, while the `Relationship` inner class encapsulates the linkage metadata. Once attached, the model can be serialized to YAML or passed directly to a converter.

## Validation and Conversion

Relationship definitions are validated during parsing and conversion. The `RelationshipMappingHandler` at [`converters/salesforce/src/main/java/org/apache/ossie/converter/RelationshipMappingHandler.java`](https://github.com/apache/ossie/blob/main/converters/salesforce/src/main/java/org/apache/ossie/converter/RelationshipMappingHandler.java) processes these relationships when converting to Salesforce format.

This handler performs two critical functions:

1. **Validation**: Any relationship that references non-existent datasets or columns is filtered out. This guarantees a consistent, usable semantic model before conversion.

2. **Transformation**: Valid relationships are transformed into `semanticRelationships` in the Salesforce payload, mapping the `from`/`to` fields and column lists to the target system's expected format.

```java
import org.apache.ossie.converter.RelationshipMappingHandler;
import org.apache.ossie.converter.ConverterConstants;
import java.util.Map;

// Assume `model` is an OsiModel instance populated with relationships
Map<String, Object> osiData = OsiModelParser.toMap(model);
RelationshipMappingHandler handler = new RelationshipMappingHandler();

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

```

The handler ensures that only valid, resolvable relationships are included in the final output, preventing runtime errors in the target system.

## Summary

- **Define relationships between datasets in Ossie** using the `relationships` array in YAML/JSON or the `Relationship` class in Java.
- Each relationship requires `name`, `from`, `to`, `from_columns`, and `to_columns` properties to specify the join conditions.
- The `OsiModelParser` deserializes YAML definitions into `OsiModel` objects.
- The `RelationshipMappingHandler` validates relationships against existing datasets and converts them to target formats like Salesforce `semanticRelationships`.
- Invalid references are automatically filtered during the validation phase to ensure model integrity.

## Frequently Asked Questions

### How does Ossie validate relationship definitions?

Ossie validates relationships during the conversion phase using the `RelationshipMappingHandler`. Any relationship referencing non-existent datasets or columns is filtered out, ensuring only valid join conditions are included in the final semantic model or target payload.

### Can I define multiple relationships between the same two datasets?

Yes. You can define multiple relationships between the same datasets by assigning unique `name` values to each entry. Each relationship can specify different column combinations for `from_columns` and `to_columns`, allowing multiple join paths between the same tables.

### What file formats does OsiModelParser support for relationship definitions?

The `OsiModelParser` supports both YAML and JSON formats. The parser reads the top-level `relationships` key and instantiates `Relationship` objects regardless of whether the source file uses YAML or JSON syntax.

### How are Ossie relationships converted to Salesforce format?

The `RelationshipMappingHandler` converts Ossie relationships to Salesforce's `semanticRelationships` structure. It maps the `from` field to the parent object, the `to` field to the child object, and preserves the column mappings (`from_columns`/`to_columns`) in the Salesforce payload format.