Relation Types Overview
Sonamu supports 4 Relation types:BelongsToOne
N:1 relationship - Many reference oneExample: Post β User (multiple posts belong to one user)
OneToOne
1:1 relationship - One references oneExample: User β Employee (user and employee info are 1:1 matched)
HasMany
1:N relationship - One owns manyExample: User β Posts (one user owns multiple posts)
ManyToMany
N:M relationship - Many-to-manyExample: 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
user_id (integer, not null)
Database structure:
Options
| Option | Type | Description | Default |
|---|---|---|---|
nullable | boolean | Allow NULL | false |
useConstraint | boolean | Use Foreign Key constraint | true |
onUpdate | RelationOn | Action on referenced record update | RESTRICT |
onDelete | RelationOn | Action on referenced record delete | RESTRICT |
customJoinClause | string | Custom JOIN condition | - |
RelationOn Options
| Value | Description | Use Case |
|---|---|---|
CASCADE | Change/delete child when parent changes | Delete posts when user is deleted |
SET NULL | Set childβs FK to NULL when parent deleted | Set employeeβs department to NULL when department deleted |
RESTRICT | Prevent parent change/delete if children exist | Cannot delete user if posts exist |
NO ACTION | Similar to RESTRICT, different check timing | - |
SET DEFAULT | Set to default value when parent deleted | - |
Example: nullable and CASCADE
department_idallowsNULL- When department is deleted, employeeβs
department_idis set toNULL
TypeScript Usage
OneToOne
1:1 relationship - Two Entities reference each other exactly once.Basic Usage
OneToOne can be defined in two ways:- hasJoinColumn: true
- hasJoinColumn: false
FK column is created in the current Entity.Generated column:
employee.entity.json
user_id (integer, unique, not null)Database structure:Options
| Option | Type | Description | Default |
|---|---|---|---|
hasJoinColumn | boolean | Whether to create FK column | required |
nullable | boolean | Allow NULL (when hasJoinColumn: true) | false |
useConstraint | boolean | FK constraint (when hasJoinColumn: true) | true |
onUpdate | RelationOn | Action on update (when hasJoinColumn: true) | RESTRICT |
onDelete | RelationOn | Action on delete (when hasJoinColumn: true) | RESTRICT |
customJoinClause | string | Custom JOIN condition | - |
Example: Bidirectional OneToOne
- 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
PostEntity must have auser_idcolumn- Usually defined with
BelongsToOnein reverse onPost
Options
| Option | Type | Description | Default |
|---|---|---|---|
joinColumn | string | FK column name in the other table | required |
fromColumn | string | Reference column name in current table | id |
nullable | boolean | Nullable for the relation itself (optional) | false |
Example: Using fromColumn
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
Options
| Option | Type | Description | Default |
|---|---|---|---|
joinTable | string | Join table name ({table1}__${table2}) | required |
onUpdate | RelationOn | Action on referenced record update | required |
onDelete | RelationOn | Action on referenced record delete | required |
nullable | boolean | Nullable for the relation itself (optional) | false |
Bidirectional Definition
TypeScript Usage
Custom Join Clause
You can write SQL expressions directly when complex JOIN conditions are needed.Relation Usage Patterns
1. Selecting Relation Fields in Subsets
user: LEFT JOINtags: Separate query via DataLoader
2. Nested Relations
3. Filtering Relations
4. Sorting by Relations
Relation Design Guide
BelongsToOne vs OneToOne
| Situation | Recommended Type | Reason |
|---|---|---|
| Post β Author | BelongsToOne | Multiple posts belong to one user |
| User β Profile | OneToOne | 1:1 matching relationship |
| Order β Customer | BelongsToOne | Multiple orders belong to one customer |
CASCADE vs RESTRICT
| Situation | Recommended Action | Reason |
|---|---|---|
| User delete β Posts | CASCADE | Delete together |
| Category delete β Posts | RESTRICT | Cannot delete if posts exist |
| Department delete β Employees | SET NULL | Keep employees, set department to NULL |
nullable Setting
| Situation | nullable | Reason |
|---|---|---|
| Required relationship | false | Reference always needed |
| Optional relationship | true | May not exist |
| Temporary state | true | Set later |