Skip to content

Commit 267d82d

Browse files
authored
Improve documentation. (#90) (#92)
1 parent 1ce57bd commit 267d82d

6 files changed

Lines changed: 54 additions & 18 deletions

File tree

docs/comparison.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,20 @@ The following tables provide a side-by-side comparison of concrete features acro
4444

4545
| Feature | Storm | JPA | Spring Data | MyBatis | jOOQ | JDBI | Exposed | Ktorm |
4646
|---------|-------|-----|-------------|---------|------|------|---------|-------|
47-
| Transactions | Both | Both | Declarative | Both | Programmatic | Both | Required | Required |
47+
| Transactions | Both | Both | Declarative | Both | Programmatic | Both | Both<sup>6</sup> | Required |
4848
| Schema validation | Yes | Yes | Via JPA | No | N/A<sup>5</sup> | No | Yes | No |
4949
| Java support | Yes | Yes | Yes | Yes | Yes | Yes | No | No |
5050
| Kotlin support | First-class | Good | Good | Good | Good | Good | Native | Native |
5151
| Coroutines | Yes | No | No | No | No | No | Yes | Limited |
5252
| Spring integration | Yes | Yes | Native | Yes | Yes | Yes | Yes | Yes |
53-
| Runtime mechanism | Codegen<sup>6</sup> | Bytecode | Bytecode | Reflection | Codegen | Reflection | Reflection | Reflection |
53+
| Runtime mechanism | Codegen<sup>7</sup> | Bytecode | Bytecode | Reflection | Codegen | Reflection | Reflection | Reflection |
5454
| Community | New | Huge | Huge | Large | Medium | Medium | Medium | Small |
5555

5656
<sup>5</sup> jOOQ generates code from the database schema, so schema validation is inherent in its code generation step.
5757

58-
<sup>6</sup> Storm uses codegen with reflection fallback.
58+
<sup>6</sup> Exposed requires `transaction {}` blocks natively, but supports declarative `@Transactional` via its Spring integration module.
59+
60+
<sup>7</sup> Storm uses codegen with reflection fallback.
5961

6062
---
6163

@@ -85,6 +87,7 @@ JPA (typically implemented by Hibernate) is the most widely used persistence fra
8587
- N+1 queries have been a recurring problem
8688
- You prefer immutable data structures
8789
- You value simplicity over complexity
90+
- You want a lightweight, minimal dependency footprint
8891
- You're using Kotlin and want idiomatic APIs
8992

9093
### When to Choose JPA/Hibernate
@@ -114,6 +117,7 @@ Spring Data JPA wraps JPA with a repository abstraction that derives query imple
114117
- You want stateless, immutable entities
115118
- You prefer explicit query logic over naming conventions
116119
- You want to avoid JPA's complexity
120+
- You want a lightweight, minimal dependency footprint
117121

118122
### When to Choose Spring Data JPA
119123

@@ -231,7 +235,7 @@ Exposed is JetBrains' official Kotlin database framework. It offers two APIs: a
231235
| **N+1 Problem** | Possible with DAO | Prevented by design; requires explicit opt-in |
232236
| **Coroutines** | Supported (added later) | First-class from the start |
233237
| **Type Safety** | Column references | Metamodel DSL |
234-
| **Transactions** | Required `transaction {}` block | Optional, programmatic + declarative |
238+
| **Transactions** | `transaction {}` block, declarative via Spring module | Optional, programmatic + declarative |
235239

236240
#### Transaction Propagation
237241

@@ -304,7 +308,6 @@ Ktorm is a lightweight Kotlin ORM that uses entity interfaces and DSL-based tabl
304308
- You're building a Kotlin-only project
305309
- You prefer no code generation
306310
- You like the Sequence API style
307-
- You want a lightweight, minimal dependency footprint
308311
- You prefer DSL-based table definitions
309312

310313
## Summary

docs/first-entity.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ Non-nullable fields (like `city: City`) produce `INNER JOIN` queries. Nullable f
3333
<TabItem value="java" label="Java">
3434

3535
```java
36+
@Builder(toBuilder = true)
3637
record City(@PK Integer id,
3738
String name,
3839
long population
3940
) implements Entity<Integer> {}
4041

42+
@Builder(toBuilder = true)
4143
record User(@PK Integer id,
4244
String email,
4345
String name,
@@ -47,6 +49,8 @@ record User(@PK Integer id,
4749

4850
In Java, record components are nullable by default. Use `@Nonnull` on fields that must always have a value. Primitive types (`int`, `long`, etc.) are inherently non-nullable.
4951

52+
The `@Builder` annotation is from [Lombok](https://projectlombok.org/) and is optional. It generates a builder that lets you construct entities without specifying the primary key, and creates modified copies via `toBuilder()`. Without Lombok, you can pass `null` as the primary key (e.g., `new City(null, "Sunnyvale", 155_000)`) or define a convenience constructor that omits it. See [Modifying Entities](entities.md#modifying-entities) for details.
53+
5054
</TabItem>
5155
</Tabs>
5256

@@ -129,10 +133,17 @@ var cities = orm.entity(City.class);
129133
var users = orm.entity(User.class);
130134

131135
// Insert a city -- the returned object has the database-generated ID
132-
City city = cities.insertAndFetch(new City(null, "Sunnyvale", 155_000));
136+
City city = cities.insertAndFetch(City.builder()
137+
.name("Sunnyvale")
138+
.population(155_000)
139+
.build());
133140

134141
// Insert a user that references the city
135-
User user = users.insertAndFetch(new User(null, "alice@example.com", "Alice", city));
142+
User user = users.insertAndFetch(User.builder()
143+
.email("alice@example.com")
144+
.name("Alice")
145+
.city(city)
146+
.build());
136147
```
137148

138149
The `insertAndFetch` method sends an INSERT statement, retrieves the auto-generated primary key, and returns a new record with the key populated.
@@ -237,7 +248,11 @@ With Spring's `@Transactional`:
237248
@Transactional
238249
public User createUser(String email, String name, City city) {
239250
return orm.entity(User.class)
240-
.insertAndFetch(new User(null, email, name, city));
251+
.insertAndFetch(User.builder()
252+
.email(email)
253+
.name(name)
254+
.city(city)
255+
.build());
241256
}
242257
```
243258

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import TabItem from '@theme/TabItem';
2323

2424
## Why Storm?
2525

26-
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
26+
Storm draws inspiration from established ORMs such as Hibernate, but is built from scratch around a clear design philosophy: capture intent using the minimum amount of code, optimized for Kotlin and modern Java.
2727

2828
**Storm's mission:** Make database development productive and enjoyable, with full developer control and high performance.
2929

website/versioned_docs/version-1.10.0/comparison.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,20 @@ The following tables provide a side-by-side comparison of concrete features acro
4444

4545
| Feature | Storm | JPA | Spring Data | MyBatis | jOOQ | JDBI | Exposed | Ktorm |
4646
|---------|-------|-----|-------------|---------|------|------|---------|-------|
47-
| Transactions | Both | Both | Declarative | Both | Programmatic | Both | Required | Required |
47+
| Transactions | Both | Both | Declarative | Both | Programmatic | Both | Both<sup>6</sup> | Required |
4848
| Schema validation | Yes | Yes | Via JPA | No | N/A<sup>5</sup> | No | Yes | No |
4949
| Java support | Yes | Yes | Yes | Yes | Yes | Yes | No | No |
5050
| Kotlin support | First-class | Good | Good | Good | Good | Good | Native | Native |
5151
| Coroutines | Yes | No | No | No | No | No | Yes | Limited |
5252
| Spring integration | Yes | Yes | Native | Yes | Yes | Yes | Yes | Yes |
53-
| Runtime mechanism | Codegen<sup>6</sup> | Bytecode | Bytecode | Reflection | Codegen | Reflection | Reflection | Reflection |
53+
| Runtime mechanism | Codegen<sup>7</sup> | Bytecode | Bytecode | Reflection | Codegen | Reflection | Reflection | Reflection |
5454
| Community | New | Huge | Huge | Large | Medium | Medium | Medium | Small |
5555

5656
<sup>5</sup> jOOQ generates code from the database schema, so schema validation is inherent in its code generation step.
5757

58-
<sup>6</sup> Storm uses codegen with reflection fallback.
58+
<sup>6</sup> Exposed requires `transaction {}` blocks natively, but supports declarative `@Transactional` via its Spring integration module.
59+
60+
<sup>7</sup> Storm uses codegen with reflection fallback.
5961

6062
---
6163

@@ -85,6 +87,7 @@ JPA (typically implemented by Hibernate) is the most widely used persistence fra
8587
- N+1 queries have been a recurring problem
8688
- You prefer immutable data structures
8789
- You value simplicity over complexity
90+
- You want a lightweight, minimal dependency footprint
8891
- You're using Kotlin and want idiomatic APIs
8992

9093
### When to Choose JPA/Hibernate
@@ -114,6 +117,7 @@ Spring Data JPA wraps JPA with a repository abstraction that derives query imple
114117
- You want stateless, immutable entities
115118
- You prefer explicit query logic over naming conventions
116119
- You want to avoid JPA's complexity
120+
- You want a lightweight, minimal dependency footprint
117121

118122
### When to Choose Spring Data JPA
119123

@@ -231,7 +235,7 @@ Exposed is JetBrains' official Kotlin database framework. It offers two APIs: a
231235
| **N+1 Problem** | Possible with DAO | Prevented by design; requires explicit opt-in |
232236
| **Coroutines** | Supported (added later) | First-class from the start |
233237
| **Type Safety** | Column references | Metamodel DSL |
234-
| **Transactions** | Required `transaction {}` block | Optional, programmatic + declarative |
238+
| **Transactions** | `transaction {}` block, declarative via Spring module | Optional, programmatic + declarative |
235239

236240
#### Transaction Propagation
237241

@@ -304,7 +308,6 @@ Ktorm is a lightweight Kotlin ORM that uses entity interfaces and DSL-based tabl
304308
- You're building a Kotlin-only project
305309
- You prefer no code generation
306310
- You like the Sequence API style
307-
- You want a lightweight, minimal dependency footprint
308311
- You prefer DSL-based table definitions
309312

310313
## Summary

website/versioned_docs/version-1.10.0/first-entity.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ Non-nullable fields (like `city: City`) produce `INNER JOIN` queries. Nullable f
3333
<TabItem value="java" label="Java">
3434

3535
```java
36+
@Builder(toBuilder = true)
3637
record City(@PK Integer id,
3738
String name,
3839
long population
3940
) implements Entity<Integer> {}
4041

42+
@Builder(toBuilder = true)
4143
record User(@PK Integer id,
4244
String email,
4345
String name,
@@ -47,6 +49,8 @@ record User(@PK Integer id,
4749

4850
In Java, record components are nullable by default. Use `@Nonnull` on fields that must always have a value. Primitive types (`int`, `long`, etc.) are inherently non-nullable.
4951

52+
The `@Builder` annotation is from [Lombok](https://projectlombok.org/) and is optional. It generates a builder that lets you construct entities without specifying the primary key, and creates modified copies via `toBuilder()`. Without Lombok, you can pass `null` as the primary key (e.g., `new City(null, "Sunnyvale", 155_000)`) or define a convenience constructor that omits it. See [Modifying Entities](entities.md#modifying-entities) for details.
53+
5054
</TabItem>
5155
</Tabs>
5256

@@ -129,10 +133,17 @@ var cities = orm.entity(City.class);
129133
var users = orm.entity(User.class);
130134

131135
// Insert a city -- the returned object has the database-generated ID
132-
City city = cities.insertAndFetch(new City(null, "Sunnyvale", 155_000));
136+
City city = cities.insertAndFetch(City.builder()
137+
.name("Sunnyvale")
138+
.population(155_000)
139+
.build());
133140

134141
// Insert a user that references the city
135-
User user = users.insertAndFetch(new User(null, "alice@example.com", "Alice", city));
142+
User user = users.insertAndFetch(User.builder()
143+
.email("alice@example.com")
144+
.name("Alice")
145+
.city(city)
146+
.build());
136147
```
137148

138149
The `insertAndFetch` method sends an INSERT statement, retrieves the auto-generated primary key, and returns a new record with the key populated.
@@ -237,7 +248,11 @@ With Spring's `@Transactional`:
237248
@Transactional
238249
public User createUser(String email, String name, City city) {
239250
return orm.entity(User.class)
240-
.insertAndFetch(new User(null, email, name, city));
251+
.insertAndFetch(User.builder()
252+
.email(email)
253+
.name(name)
254+
.city(city)
255+
.build());
241256
}
242257
```
243258

website/versioned_docs/version-1.10.0/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import TabItem from '@theme/TabItem';
2323

2424
## Why Storm?
2525

26-
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
26+
Storm draws inspiration from established ORMs such as Hibernate, but is built from scratch around a clear design philosophy: capture intent using the minimum amount of code, optimized for Kotlin and modern Java.
2727

2828
**Storm's mission:** Make database development productive and enjoyable, with full developer control and high performance.
2929

0 commit comments

Comments
 (0)