You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+34-4Lines changed: 34 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,7 @@
10
10
11
11
**Storm** is a modern, high-performance ORM for Kotlin 2.0+ and Java 21+, built around a powerful SQL template engine. It focuses on simplicity, type safety, and predictable performance through immutable models and compile-time metadata.
12
12
13
-
**Key benefits:**
13
+
**Core ORM benefits:**
14
14
15
15
-**Minimal code**: Define entities with simple records/data classes and query with concise, readable syntax; no boilerplate.
16
16
-**Parameterized by default**: String interpolations are automatically converted to bind variables, making queries SQL injection safe by design.
@@ -21,6 +21,17 @@
21
21
-**Performance**: Template caching, transaction-scoped entity caching, and zero-overhead dirty checking (thanks to immutability) ensure efficient database interactions. Batch processing, lazy streams, and upserts are built in.
22
22
-**Universal Database Compatibility**: Fully compatible with all SQL databases, it offers flexibility and broad applicability across various database systems.
23
23
24
+
Storm also includes an AI-assisted workflow for database development. It gives AI tools full schema awareness through a local MCP server, guides them with Storm-specific skills, and closes the loop with automated tests. The AI generates code, but the final checks are done by running code against the schema and captured SQL, not by trusting LLM reasoning.
25
+
26
+
To set up the AI workflow in your project:
27
+
28
+
```bash
29
+
npm install -g @storm-orm/cli
30
+
storm init
31
+
```
32
+
33
+
This installs Storm's rules, skills, and optional local MCP setup for supported AI coding tools. See [AI-Assisted Development](docs/ai.md) for the full workflow.
34
+
24
35
## Why Storm?
25
36
26
37
Storm draws inspiration from established ORMs such as Hibernate, but is built from scratch around a clear design philosophy: capturing exactly what you want to do using the minimum amount of code, optimized for Kotlin and modern Java.
@@ -42,6 +53,25 @@ Storm embraces SQL rather than abstracting it away. It simplifies database inter
42
53
43
54
**Storm is ideal for** developers who understand that the best solutions emerge when object model and database model work in harmony. If you value a database-first approach where records naturally mirror your schema, Storm is built for you. Custom mappings are supported when needed, but the real elegance comes from alignment, not abstraction.
44
55
56
+
## AI Workflow
57
+
58
+
AI tools can write a lot of database code quickly, but subtle mistakes are still common: wrong joins, missing constraints, stale schema assumptions, or queries that compile but do the wrong thing.
59
+
60
+
Storm addresses that in two ways.
61
+
62
+
First, it improves generation quality. A local MCP server gives the AI full schema awareness without exposing credentials or data, and Storm skills teach the AI how to create entities, queries, repositories, and migrations that follow Storm's conventions.
63
+
64
+
Second, it verifies the result with automated tests. Storm can validate that generated entities still match the schema and that generated queries behave as intended. These checks run in unit tests, so the final gate is actual code execution rather than model self-evaluation.
65
+
66
+
The workflow is simple:
67
+
68
+
1. You prompt the AI.
69
+
2. The AI uses Storm skills and local schema context to generate code.
70
+
3. Storm verifies the generated entities and queries in tests.
71
+
4. You review the result and keep moving with more confidence.
72
+
73
+
This is the core idea: AI generates database code, and Storm closes the loop with context and verification.
74
+
45
75
## Choose Your Language
46
76
47
77
Both Kotlin and Java support SQL Templates for powerful query composition. Kotlin additionally provides a type-safe DSL with infix operators for a more idiomatic experience.
@@ -143,7 +173,7 @@ Storm provides a Bill of Materials (BOM) for centralized version management. Imp
143
173
<dependency>
144
174
<groupId>st.orm</groupId>
145
175
<artifactId>storm-bom</artifactId>
146
-
<version>1.11.0</version>
176
+
<version>@@STORM_VERSION@@</version>
147
177
<type>pom</type>
148
178
<scope>import</scope>
149
179
</dependency>
@@ -155,7 +185,7 @@ Storm provides a Bill of Materials (BOM) for centralized version management. Imp
@@ -33,7 +33,7 @@ The Kotlin API does not depend on any preview features. All APIs are stable and
33
33
Spring Framework integration for Kotlin. Provides `RepositoryBeanFactoryPostProcessor` for repository auto-discovery and injection, `@EnableTransactionIntegration` for bridging Storm's programmatic transactions with Spring's `@Transactional`, and transaction-aware coroutine support. Add this module when you use Spring Framework without Spring Boot.
See [Spring Integration](spring-integration.md) for configuration details.
@@ -43,7 +43,7 @@ See [Spring Integration](spring-integration.md) for configuration details.
43
43
Spring Boot auto-configuration for Kotlin. Automatically creates an `ORMTemplate` bean from the `DataSource`, discovers repositories, enables transaction integration, and binds `storm.*` properties from `application.yml`. This is the recommended dependency for Spring Boot applications.
See [Spring Integration: Spring Boot Starter](spring-integration.md#spring-boot-starter) for what the starter provides and how to override its defaults.
Copy file name to clipboardExpand all lines: docs/batch-streaming.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ Database performance often degrades when applications issue many individual SQL
12
12
13
13
## Batch Processing
14
14
15
-
When you pass a list of entities to Storm's insert, update, delete, or upsert methods, Storm automatically uses JDBC batch statements. The framework groups rows together and sends them to the database in a single round-trip, rather than issuing one statement per entity.
15
+
When you pass a list of entities to Storm's insert, update, remove, or upsert methods, Storm automatically uses JDBC batch statements. The framework groups rows together and sends them to the database in a single round-trip, rather than issuing one statement per entity.
Each method returns a `Window` containing the page content and navigation cursors for sequential traversal. The `hasNext()` and `hasPrevious()` flags reflect whether additional rows existed at query time, but they are not prerequisites for calling `nextScrollable()` or `previousScrollable()`. Both methods return a non-null `Scrollable` whenever the window contains at least one element, and return `null` only when the window is empty. This means you can always follow the cursor if you choose to; for example, new rows may have been inserted after the original query. For REST APIs, `Window` also provides `nextCursor()` and `previousCursor()` to serialize the scroll position as an opaque string, and `Scrollable.fromCursor(key, cursor)` to reconstruct a `Scrollable` from a cursor string. See [Repositories: Scrolling](repositories.md#scrolling) for the full API, including sort overloads, filtering, and Ref variants.
485
+
Each method returns a `Window` containing the page content and navigation cursors for sequential traversal. The `hasNext()` and `hasPrevious()` flags reflect whether additional rows existed at query time, but they are not prerequisites for calling `next()` or `previous()`. Both methods return a non-null `Scrollable` whenever the window contains at least one element, and return `null` only when the window is empty. This means you can always follow the cursor if you choose to; for example, new rows may have been inserted after the original query. For REST APIs, `Window` also provides `nextCursor()` and `previousCursor()` to serialize the scroll position as an opaque string, and `Scrollable.fromCursor(key, cursor)` to reconstruct a `Scrollable` from a cursor string. See [Repositories: Scrolling](repositories.md#scrolling) for the full API, including sort overloads, filtering, and Ref variants.
486
486
487
487
### Choosing Between the Two
488
488
@@ -496,8 +496,8 @@ Each method returns a `Window` containing the page content and navigation cursor
496
496
| Performance at page 1 | Good | Good |
497
497
| Performance at page 1,000 | Degrades (database must skip rows) | Consistent (index seek) |
498
498
| Handles concurrent inserts | Rows may shift between pages | Stable cursor |
Use pagination when you need random page access or a total count (for example, displaying "Page 3 of 12" in a UI). Use scrolling when you need consistent performance over deep result sets or when the data changes frequently between requests.
Copy file name to clipboardExpand all lines: docs/cursors.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -85,7 +85,7 @@ The following Java types can be used as cursor values (key or sort fields) out o
85
85
86
86
If your key or sort field uses a type not in this list, serialization via `toCursor()` will throw an `IllegalStateException`. You can either use one of the supported types for your key/sort columns, or register a custom codec.
87
87
88
-
Note that in-memory navigation (using `nextScrollable()` and `previousScrollable()` directly, without serializing to a cursor string) works with any type, including inline records and other composite types. The type restriction only applies to `toCursor()` serialization.
88
+
Note that in-memory navigation (using `next()` and `previous()` directly, without serializing to a cursor string) works with any type, including inline records and other composite types. The type restriction only applies to `toCursor()` serialization.
0 commit comments