Bx orm relationships
Skill ortus-boxlang/skills/boxlang-modules/bx-orm/bx-orm-relationships
BoxLang AI skills repository and Claude Plugin
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.
What its author says it does
Copied from the file, not written here
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.
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.