Bx orm relationships
Skill ortus-boxlang/skills/boxlang-modules/bx-orm/bx-orm-relationships
Use this skill when defining relationships between ORM entities: one-to-one, one-to-many, many-to-one, many-to-many, lazy loading, cascade options, foreign keys, link tables, singular names, and inverse relationships.From its SKILL.md
npx -y skills add ortus-boxlang/skills --skill bx-orm-relationshipsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.3 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it
bx-orm: Entity Relationships
Relationship Overview
| Type | Use Case | Example |
|---|---|---|
one-to-one | Single associated record | User → Address |
one-to-many | Parent with collection | User → Posts |
many-to-one | Child pointing to parent | Post → Author |
many-to-many | Bidirectional multi | Author ↔ Book |
Every relationship property uses fieldtype to declare its kind.
One-to-One
// Contact.bx — has one Address
class persistent="true" entityName="Contact" {
property name="id" fieldtype="id" generator="native";
property name="name" type="string";
// One-to-one: each Contact has exactly one Address
property name="address"
fieldtype = "one-to-one"
class = "Address";
}
Set lazy="false" to eagerly load the related entity:
property name="address"
fieldtype = "one-to-one"
class = "Address"
lazy = "false";
One-to-Many
// User.bx — has many Posts
class persistent="true" entityName="User" {
property name="id" fieldtype="id" generator="native";
property name="email" type="string";
// One-to-many: a User has many Posts
property name="posts"
fieldtype = "one-to-many"
class = "Post"
fkcolumn = "author_id" // FK column in the posts table
lazy = "true"
singularName= "post"; // enables addPost(), removePost()
}
Accessing the collection:
user = entityLoadByPK( "User", 1 )
posts = user.getPosts() // returns array of Post entities
user.addPost( newPost ) // uses singularName
user.removePost( oldPost ) // uses singularName
user.hasPosts() // boolean
Many-to-One
// Post.bx — belongs to one Author (User)
class persistent="true" entityName="Post" {
property name="id" fieldtype="id" generator="native";
property name="title" type="string";
// Many-to-one: many Posts share one Author
property name="author"
fieldtype = "many-to-one"
class = "User"
fkcolumn = "author_id";
}
post = entityLoadByPK( "Post", 42 )
author = post.getAuthor() // returns User entity
Many-to-Many
// Author.bx — can write many Books; Books can have many Authors
class persistent="true" entityName="Author" {
property name="id" fieldtype="id" generator="native";
property name="name" type="string";
property name="books"
fieldtype = "many-to-many"
class = "Book"
linktable = "author_books" // join table
fkcolumn = "author_id" // this entity's FK in join table
inversejoin = "book_id" // other entity's FK in join table
singularName= "book";
}
// Book.bx — inverse side
class persistent="true" entityName="Book" {
property name="id" fieldtype="id" generator="native";
property name="title" type="string";
property name="authors"
fieldtype = "many-to-many"
class = "Author"
linktable = "author_books"
fkcolumn = "book_id"
inversejoin = "author_id"
singularName= "author";
}
Relationship Property Annotations
| Annotation | Description |
|---|---|
fieldtype | Relationship type: one-to-one, one-to-many, many-to-one, many-to-many |
class | FULLY qualified path or entity name of the related class |
fkcolumn | Foreign key column name |
linktable | Join table name (many-to-many only) |
inversejoin | FK column for the other entity in the join table |
lazy | "true" (default) or "false" for eager loading |
cascade | "all", "save-update", "delete", "none" |
singularName | Singular form — enables addX(), removeX(), hasX() methods |
orderBy | Default sort column(s) for collections |
where | SQL WHERE clause to filter the collection |
fetch | "select" or "join" fetching strategy |
Cascade Options
// Cascade save/delete to child records
property name="posts"
fieldtype = "one-to-many"
class = "Post"
fkcolumn = "user_id"
cascade = "all"; // save, update, and delete cascade
// Cascade save only (not delete)
property name="address"
fieldtype = "one-to-one"
class = "Address"
cascade = "save-update";
| Cascade Value | Behavior |
|---|---|
none | No cascade |
save-update | Cascade save and update operations |
delete | Cascade delete only |
all | Cascade save, update, and delete |
all-delete-orphan | all + delete orphaned records |
Lazy vs Eager Loading
// Lazy (default) — related entity loaded only when accessed
property name="posts" fieldtype="one-to-many" class="Post" lazy="true";
// Eager — loads related entity in the same SQL query
property name="address" fieldtype="one-to-one" class="Address" lazy="false";
Recommendation: Use lazy="true" (default) for collections (one-to-many, many-to-many) and consider lazy="false" only for single-record relationships (one-to-one) where you always need the related data.
N+1 Problem Prevention
Use batchSize to batch-load related entities:
// Entity-level batchSize
class persistent="true" entityName="Post" batchSize="20" {
// ...
}
// Relationship-level batchSize
property name="comments"
fieldtype = "one-to-many"
class = "Comment"
fkcolumn = "post_id"
batchSize = "20";
Common Pitfalls
- ❌ Do NOT forget
fkcolumnon one-to-many and many-to-one — Hibernate cannot infer it - ❌ Do NOT use
lazy="false"on large collections — will load thousands of records - ❌ Do NOT forget
linktableon many-to-many — it is required - ✅ Always set
singularNameon collection relationships for cleanaddX()/removeX()API - ✅ Use
cascade="all-delete-orphan"on owned one-to-many collections (e.g., order → line items) - ✅ Define both sides of many-to-many relationships with matching
linktablevalues
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.