Skip to main content
Relations define associations between Entities to ensure database referential integrity and enable type-safe join queries.

Relation Types Overview

Sonamu supports 4 Relation types:

BelongsToOne

N:1 relationship - Many reference one Example: Post β†’ User (multiple posts belong to one user)

OneToOne

1:1 relationship - One references one Example: User ↔ Employee (user and employee info are 1:1 matched)

HasMany

1:N relationship - One owns many Example: User β†’ Posts (one user owns multiple posts)

ManyToMany

N:M relationship - Many-to-many Example: Post ↔ Tag (many-to-many between posts and tags)

BelongsToOne

N:1 relationship - The current Entity belongs to another Entity.

Basic Usage

post.entity.json
Generated column: user_id (integer, not null) Database structure:

Options

RelationOn Options

Example: nullable and CASCADE

Behavior:
  • department_id allows NULL
  • When department is deleted, employee’s department_id is set to NULL

TypeScript Usage

OneToOne

1:1 relationship - Two Entities reference each other exactly once.

Basic Usage

OneToOne can be defined in two ways:
FK column is created in the current Entity.
employee.entity.json
Generated column: user_id (integer, unique, not null)Database structure:

Options

Example: Bidirectional OneToOne

Relationship explained:
  • User can optionally have an Employee (nullable)
  • Employee must have a User (not null)
  • When User is deleted, Employee is also deleted (CASCADE)

HasMany

1:N relationship - One Entity owns multiple other Entities.

Basic Usage

user.entity.json
Requirements:
  • Post Entity must have a user_id column
  • Usually defined with BelongsToOne in reverse on Post

Options

Example: Using fromColumn

JOIN query:

TypeScript Usage

HasMany is automatically optimized using the DataLoader pattern. N+1 query problems don’t occur.

ManyToMany

N:M relationship - Many-to-many relationship implemented through a join table.

Basic Usage

post.entity.json
Auto-generated Join Table:

Options

Join Table Naming Convention: Sort two table names alphabetically and connect with __. - Correct: posts__tags - Wrong: tags__posts (not alphabetical order)

Bidirectional Definition

TypeScript Usage

Custom Join Clause

You can write SQL expressions directly when complex JOIN conditions are needed.
customJoinClause is an advanced feature. Use standard Relations when possible.

Relation Usage Patterns

1. Selecting Relation Fields in Subsets

Auto-generated queries:
  • user: LEFT JOIN
  • tags: Separate query via DataLoader

2. Nested Relations

Sonamu automatically generates the necessary JOINs:

3. Filtering Relations

4. Sorting by Relations

Relation Design Guide

BelongsToOne vs OneToOne

CASCADE vs RESTRICT

nullable Setting

Cautions

Avoid Circular ReferencesAvoid circular references like A β†’ B β†’ C β†’ A. This can cause problems when creating data.
JOIN Depth LimitToo deep nested Relations (3+ levels) can cause performance issues. Separate into different queries when needed.
ManyToMany Join TableSonamu automatically manages Join Tables, so you don’t need to create a separate Entity. Only separate into an Entity when additional columns are needed.

Next Steps

Enums

Define and use Enum types

Subset

Type-safe queries with Subsets

Puri Query Builder

Write queries using Relations

Performance

Optimize Relation queries