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
@@ -116,11 +145,13 @@ Upsert operations are the primary reason most applications need a dialect. Witho
116
145
117
146
| Database | SQL Strategy | Conflict Detection |
118
147
|----------|--------------|--------------------|
148
+
| Oracle |`MERGE INTO ...`| Explicit match conditions |
149
+
| MS SQL Server |`MERGE INTO ...`| Explicit match conditions |
119
150
| PostgreSQL |`INSERT ... ON CONFLICT DO UPDATE`| Targets a specific unique constraint or index |
120
151
| MySQL |`INSERT ... ON DUPLICATE KEY UPDATE`| Primary key or any unique constraint |
121
152
| MariaDB |`INSERT ... ON DUPLICATE KEY UPDATE`| Primary key or any unique constraint |
122
-
|Oracle|`MERGE INTO ...`|Explicit match conditions|
123
-
|MS SQL Server|`MERGE INTO ...`| Explicit match conditions |
153
+
|SQLite|`INSERT ... ON CONFLICT DO UPDATE`|Targets a specific unique constraint|
154
+
|H2|`MERGE INTO ...`| Explicit match conditions |
124
155
125
156
See [Upserts](upserts.md) for usage examples.
126
157
@@ -132,23 +163,53 @@ PostgreSQL's JSONB and MySQL/MariaDB's JSON types are fully supported when using
132
163
133
164
Beyond SQL syntax differences, databases support different native data types. Dialects handle the mapping between Kotlin/Java types and database-specific types automatically, so you can use idiomatic types in your entities without worrying about the underlying storage format.
134
165
135
-
-**PostgreSQL:** JSONB, UUID, arrays, INET, CIDR
136
-
-**MySQL/MariaDB:** JSON, TINYINT for booleans, ENUM
137
166
-**Oracle:** NUMBER, CLOB, sequences for ID generation
Storm works without a specific dialect package by generating standard SQL. This is the typical setup during development and testing when using H2 as an in-memory database. The core framework handles entity mapping, queries, joins, transactions, streaming, dirty checking, and caching using only standard SQL. However, some features require database-specific syntax and will be unavailable without a dialect:
175
+
Storm works without a specific dialect package by generating standard SQL. The core framework handles entity mapping, queries, joins, transactions, streaming, dirty checking, and caching using only standard SQL. However, some features require database-specific syntax and will be unavailable without a dialect:
-**Database-specific optimizations** such as native pagination strategies
146
179
147
180
All other features (entity mapping, queries, joins, transactions, streaming, dirty checking, and caching) work identically regardless of dialect.
148
181
182
+
## Testing with SQLite
183
+
184
+
SQLite is a lightweight option for testing. It stores data in a single file (or in memory) and requires no server process. Add the `storm-sqlite` dialect dependency to enable SQLite-specific features like upsert support.
185
+
186
+
<TabsgroupId="language">
187
+
<TabItemvalue="kotlin"label="Kotlin"default>
188
+
189
+
```kotlin
190
+
val dataSource =SQLiteDataSource().apply {
191
+
url ="jdbc:sqlite::memory:"
192
+
}
193
+
val orm =ORMTemplate.of(dataSource)
194
+
```
195
+
196
+
</TabItem>
197
+
<TabItemvalue="java"label="Java">
198
+
199
+
```java
200
+
var dataSource =newSQLiteDataSource();
201
+
dataSource.setUrl("jdbc:sqlite::memory:");
202
+
var orm =ORMTemplate.of(dataSource);
203
+
```
204
+
205
+
</TabItem>
206
+
</Tabs>
207
+
208
+
Note that SQLite does not support sequences, row-level locking, or `INFORMATION_SCHEMA`. Constraint discovery uses JDBC metadata, and locking relies on SQLite's file-level locking mechanism.
209
+
149
210
## Testing with H2
150
211
151
-
H2 is an in-memory Java SQL database that starts instantly and requires no external processes. Storm includes built-in support for H2, making it the default choice for unit tests. Because H2 runs in-process, tests start in milliseconds and do not require Docker, network access, or database installation.
212
+
H2 is an in-memory Java SQL database that starts instantly and requires no external processes, making it the default choice for unit tests. Because H2 runs in-process, tests start in milliseconds and do not require Docker, network access, or database installation.
152
213
153
214
<TabsgroupId="language">
154
215
<TabItemvalue="kotlin"label="Kotlin"default>
@@ -172,7 +233,7 @@ var orm = ORMTemplate.of(dataSource);
172
233
</TabItem>
173
234
</Tabs>
174
235
175
-
No additional dialect dependency is needed for H2. This makes it easy to write fast tests that run without Docker or external databases.
236
+
For basic testing without upsert support, H2 works without any dialect dependency. To enable upsert support and other H2-specific optimizations (native UUID handling, tuple comparisons), add the `storm-h2` dialect dependency.
176
237
177
238
## Integration Testing with Real Databases
178
239
@@ -187,10 +248,10 @@ mvn test -pl storm-postgresql
187
248
## Tips
188
249
189
250
1.**Always include the dialect** for production databases to unlock all features
190
-
2.**Use H2** for unit tests; no additional dialect needed, fast startup
251
+
2.**Use H2 or SQLite** for unit tests; add `storm-h2` or `storm-sqlite` for upsert support
191
252
3.**Dialect is runtime-only**; it doesn't affect your compile-time code or entity definitions
192
253
4.**One dialect per application**; Storm auto-detects the right dialect from your connection URL
193
-
5.**Test with both**: Use H2 for fast unit tests and the production dialect for integration tests
254
+
5.**Test with both**: Use H2/SQLite for fast unit tests and the production dialect for integration tests
Copy file name to clipboardExpand all lines: docs/getting-started.md
+46-7Lines changed: 46 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,32 +18,71 @@ The framework is organized around three core abstractions:
18
18
19
19
These abstractions share a common principle: explicit behavior over implicit magic. Every query is visible in the source code. Every relationship is loaded when you ask for it. Every transaction boundary is declared, not inferred. This makes Storm applications straightforward to debug, profile, and reason about.
20
20
21
-
## How Storm Differs from JPA
21
+
## Choose Your Path
22
22
23
-
If you are coming from JPA/Hibernate, the biggest shift is moving from mutable, proxy-backed entities with a managed lifecycle to stateless, immutable values. Storm has no persistence context, no first-level cache, no `EntityManager`, and no automatic change detection. This eliminates entire categories of bugs (LazyInitializationException, detached entity errors, unexpected flush ordering) while making performance predictable. For a detailed comparison, see the [Migration from JPA](migration-from-jpa.md) guide and the [Storm vs Other Frameworks](comparison.md) feature comparison.
23
+
Storm supports two ways to get started. Pick the one that fits your workflow.
24
24
25
-
## Step-by-Step Setup
25
+
import Tabs from '@theme/Tabs';
26
+
import TabItem from '@theme/TabItem';
26
27
27
-
This guide is split into three steps. Follow them in order for the fastest path from zero to a working application.
28
+
<Tabs>
29
+
<TabItemvalue="ai"label="AI-Assisted"default>
28
30
29
-
## 1. Installation
31
+
### AI-Assisted Setup
32
+
33
+
If you use an AI coding tool (Claude Code, Cursor, GitHub Copilot, Windsurf, or Codex), Storm provides rules, skills, and an optional database-aware MCP server that give the AI deep knowledge of Storm's conventions. The AI can generate entities from your schema, write queries, and verify its own work against a real database.
34
+
35
+
**1. Install the Storm CLI and run it in your project:**
36
+
37
+
```bash
38
+
npx @storm-orm/cli init
39
+
```
40
+
41
+
The interactive setup configures your AI tool with Storm's rules and skills, and optionally connects it to your development database for schema-aware code generation.
42
+
43
+
**2. Ask your AI tool to set up Storm:**
44
+
45
+
Once `storm init` has configured your tool, you can ask it to add the right dependencies, create entities from your database tables, and write queries. The AI has access to Storm's full documentation and your database schema.
46
+
47
+
For example:
48
+
- "Add Storm to this project with Spring Boot and PostgreSQL"
49
+
- "Create entities for the users and orders tables"
50
+
- "Write a repository method that finds orders by status with pagination"
51
+
52
+
**3. Verify:**
53
+
54
+
Storm's AI workflow includes built-in verification. The AI can run `ORMTemplate.validateSchema()` to prove entities match the database and `SqlCapture` to inspect generated SQL, all in an isolated H2 test database before anything touches production.
55
+
56
+
See [AI-Assisted Development](ai.md) for the full setup guide, available skills, and MCP server configuration.
57
+
58
+
</TabItem>
59
+
<TabItemvalue="manual"label="Manual">
60
+
61
+
### Manual Setup
62
+
63
+
Follow these three steps in order for the fastest path from zero to a working application.
64
+
65
+
**1. Installation**
30
66
31
67
Set up your project with the right dependencies, build flags, and optional modules.
32
68
33
69
**[Go to Installation](installation.md)**
34
70
35
-
## 2. First Entity
71
+
**2. First Entity**
36
72
37
73
Define your first entity, create an ORM template, and perform insert, read, update, and delete operations.
38
74
39
75
**[Go to First Entity](first-entity.md)**
40
76
41
-
## 3. First Query
77
+
**3. First Query**
42
78
43
79
Write custom queries, build repositories, stream results, and use the type-safe metamodel.
0 commit comments