Onyx Cloud Database API
Cascade Save in Onyx Cloud
Cascade save lets you persist an entire object graph—such as a parent entity and its related children—in a single request. The server saves the parent and then its related children. This reduces client requests, but the graph is not committed as a single transaction.
When to Use Cascade Save
Use cascade save for onboarding workflows, configuration screens, and forms that save a parent with related children. A later failure can leave earlier entities saved; design retries and recovery for partially completed requests.
- Persisting nested form data (for example, a movie with its actors or an invoice with line items).
- Importing related data with explicit identifier mappings and verification after saving.
- Reducing round trips from the browser or server by eliminating manual save ordering.
Prerequisites
Before triggering a cascade save, make sure that your schema defines the parent and child tables along with the foreign keys you plan to hydrate. Cascade behavior itself is configured entirely through the db.cascade() helper—no additional schema cascadePolicy is required.
Understand Cascade Paths
The string passed to db.cascade() defines which relationships should cascade and how to map identifiers. The format is:
relationshipName:RelatedEntity(foreignKeyAttribute, primaryKeyAttribute)
- relationshipName: matches the relationship defined on the parent entity.
- RelatedEntity: the entity type for the related records.
- foreignKeyAttribute: the attribute on the related entity that points back to the parent.
- primaryKeyAttribute: the primary key attribute on the parent entity.
You can chain multiple relationships—for example "orders:Order(customerId, id).lineItems:LineItem(orderId, id)"—to cascade through deeper graphs.
1await db.cascade('actors:Actor(movieId, id)')
2 .save('Movie', movieWithActors);Tutorial: Saving a Movie with Actors
Follow the steps below to persist a movie and its actors in a single cascade save operation.
Prepare the Movie Graph
Assemble the parent entity with its related actors. Each actor has a stable identifier so that repeated saves update the same records.
1const movieWithActors = {
2 id: 'movie_001',
3 title: 'Inception',
4 releaseYear: 2010,
5 genre: 'Sci-Fi',
6 actors: [
7 {
8 id: 'actor_001',
9 name: 'Leonardo DiCaprio',
10 role: 'Cobb'
11 },
12 {
13 id: 'actor_002',
14 name: 'Marion Cotillard',
15 role: 'Mal'
16 },
17 {
18 id: 'actor_003',
19 name: 'Tom Hardy',
20 role: 'Eames'
21 }
22 ]
23};Execute the Cascade Save
Use the cascade helper to persist the movie and all actors in one call. The cascade path ensures that the movieId foreign key on each actor is bound to the movie's id.
1await db.cascade('actors:Actor(movieId, id)')
2 .save('Movie', movieWithActors);Cascade save has no graph-wide rollback. If a child fails validation, the parent and earlier children may already be stored. Inspect the saved records, correct the error, and retry with stable identifiers; restore or remove partial writes explicitly when needed.
Verify the Persisted Graph
Query the movie and resolve the actors relationship to confirm the cascade save populated the child records. The eq helper scopes the lookup to the saved identifier.
1const savedMovie = await db
2 .from('Movie')
3 .resolve('actors')
4 .where(eq('id', 'movie_001'))
5 .firstOrNull();
6
7db.results = savedMovie;Troubleshooting & Best Practices
- Missing identifiers: Ensure that every entity in the graph has its identifier set. Use Onyx sequence values or UUIDs before calling
save. - Mismatched keys: If children fail to associate, verify the foreign key attribute in the cascade path matches the relationship definition.
- Large graphs: Batch very large imports into smaller graphs, and verify each batch so that partial failures can be recovered.
- Idempotent updates: Provide stable identifiers so that running the same cascade save again updates existing records instead of inserting duplicates.
Continue Building with Onyx Cloud
Need Help?
If you have any questions or need assistance:
- Email:support@onyx.dev
- Documentation: Visit ourHelp Centerfor tutorials and FAQs.