diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a21ae8d76..ab4b70b18 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,9 +51,21 @@ jobs: - name: Copy Javadoc to website/static/api/java run: | mkdir -p website/static/api/java - if [ -d target/reports/apidocs ]; then - cp -r target/reports/apidocs/* website/static/api/java/ + # The aggregate report goal writes under the reporting output dir: + # target/site/apidocs on Maven 3.x, target/reports/apidocs on Maven 4.x. + copied="" + for src in target/site/apidocs target/reports/apidocs; do + if [ -d "$src" ]; then + cp -r "$src"/* website/static/api/java/ + copied="$src" + break + fi + done + if [ -z "$copied" ]; then + echo "::error::Aggregate Javadoc not found (checked target/site/apidocs and target/reports/apidocs); /api/java/index.html would 404" + exit 1 fi + echo "Copied aggregate Javadoc from $copied" - name: Copy KDoc to website/static/api/kotlin run: | diff --git a/docs/configuration.md b/docs/configuration.md index 1210340c3..412c1b156 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -605,7 +605,7 @@ Controls whether record (structural) validation runs when Storm first encounters | `warn` | Errors are logged as warnings; startup continues. | | `none` | Record validation is skipped entirely. | -### storm.validation.schema_mode +### storm.validation.schema_mode {#schema-validation} Controls whether schema validation runs at startup (Spring Boot only; for programmatic use, see [Validation](validation.md#programmatic-api)). diff --git a/docs/faq.md b/docs/faq.md index eb6bbf037..c0d13974e 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -67,7 +67,7 @@ Storm never issues DDL statements (CREATE TABLE, ALTER TABLE, DROP TABLE). It re ### No Lazy-Loading Proxies -Storm does not use bytecode manipulation or runtime proxies to intercept field access. This eliminates `LazyInitializationException`, hidden database queries, and session-dependent entity behavior. Relationships declared with `@FK` are loaded eagerly in a single query. When you need deferred loading (for example, a rarely-accessed large sub-graph), use `Ref` to make the database access explicit and intentional. See [Entities: Deferred Loading](entities.md#deferred-loading-with-ref) for details. +Storm does not use bytecode manipulation or runtime proxies to intercept field access. This eliminates `LazyInitializationException`, hidden database queries, and session-dependent entity behavior. Relationships declared with `@FK` are loaded eagerly in a single query. When you need deferred loading (for example, a rarely-accessed large sub-graph), use `Ref` to make the database access explicit and intentional. See [Refs: Deferred Loading](refs.md#deferred-loading) for details. ### No Second-Level Cache diff --git a/docs/getting-started.md b/docs/getting-started.md index 9e45aeb15..148e04f25 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -6,7 +6,7 @@ Storm is a modern SQL Template and ORM framework for Kotlin 2.0+ and Java 21+. I Storm is built around a simple idea: your data model should be a plain value, not a framework-managed object. In Storm, entities are Kotlin data classes or Java records. They carry no hidden state, no change-tracking proxies, and no lazy-loading hooks. You can create them, pass them across layers, serialize them, compare them by value, and store them in collections without worrying about session scope, detachment, or side effects. What you see in the source code is exactly what exists at runtime. -This stateless design is a deliberate trade-off. Traditional ORMs like JPA/Hibernate give you transparent lazy loading and proxy-based dirty checking, but at the cost of complexity: you must reason about managed vs. detached state, proxy initialization, persistence context boundaries, and cascading rules that interact in subtle ways. Storm avoids all of this. It still performs [dirty checking](/dirty-checking), but by comparing entity state within a transaction rather than through proxies or bytecode manipulation. When you query a relationship, you get the result in the same query. There are no surprises. +This stateless design is a deliberate trade-off. Traditional ORMs like JPA/Hibernate give you transparent lazy loading and proxy-based dirty checking, but at the cost of complexity: you must reason about managed vs. detached state, proxy initialization, persistence context boundaries, and cascading rules that interact in subtle ways. Storm avoids all of this. It still performs [dirty checking](dirty-checking.md), but by comparing entity state within a transaction rather than through proxies or bytecode manipulation. When you query a relationship, you get the result in the same query. There are no surprises. Storm is also SQL-first. Rather than abstracting SQL away behind a query language (like JPQL) or a verbose criteria builder, Storm embraces SQL directly. Its SQL Template API lets you write real SQL with type-safe parameter interpolation and automatic result mapping. For common CRUD patterns, the type-safe DSL and repository interfaces provide concise, compiler-checked alternatives, but the full power of SQL is always available when you need it. diff --git a/docs/index.md b/docs/index.md index 2dab352ea..b891edc0f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -236,7 +236,7 @@ If you are a tech lead or architect evaluating Storm for a production system, th Storm is focused on being a great ORM and SQL template engine. It intentionally does not include: -- **Schema migration or DDL generation.** Storm does not automatically create, alter, or drop tables at runtime. With Storm's [AI integration](/ai), your coding assistant can read your database schema and generate Flyway or Liquibase migration scripts on demand. For schema versioning, use [Flyway](https://flywaydb.org/) or [Liquibase](https://www.liquibase.com/). +- **Schema migration or DDL generation.** Storm does not automatically create, alter, or drop tables at runtime. With Storm's [AI integration](ai.md), your coding assistant can read your database schema and generate Flyway or Liquibase migration scripts on demand. For schema versioning, use [Flyway](https://flywaydb.org/) or [Liquibase](https://www.liquibase.com/). - **Second-level cache.** Storm's entity cache is transaction-scoped and cleared on commit. For cross-transaction caching, use Spring's `@Cacheable` or a dedicated cache layer like Caffeine or Redis. - **Lazy loading proxies.** Entities are plain records with no proxies. Related entities are loaded eagerly in a single query via JOINs. For deferred loading, use [Refs](refs.md) to explicitly control when related data is fetched. diff --git a/docs/relationships.md b/docs/relationships.md index ad891c745..2692be329 100644 --- a/docs/relationships.md +++ b/docs/relationships.md @@ -68,8 +68,8 @@ data class User( When you query a `User`, the related `City` is automatically loaded: ```kotlin -val user = orm.find(User_.id eq userId) -println(user?.city.name) // City is already loaded +val user = orm.get(User_.id eq userId) +println(user.city.name) // City is already loaded ``` diff --git a/website/src/pages/index.js b/website/src/pages/index.js index b04b5df33..72e5c1269 100644 --- a/website/src/pages/index.js +++ b/website/src/pages/index.js @@ -327,7 +327,7 @@ export default function Home() { 'FROM "user" u\n'+ 'INNER JOIN city c ON c.id = u.city_id\n'+ 'WHERE c.country = ?\n'+ - 'GROUP BY c.id, c.name, c.population, c.country\n'+ + 'GROUP BY u.city_id\n'+ 'ORDER BY COUNT(*) DESC\n'+ 'LIMIT ?', diff --git a/website/versioned_docs/version-1.11.5/configuration.md b/website/versioned_docs/version-1.11.5/configuration.md index 1210340c3..412c1b156 100644 --- a/website/versioned_docs/version-1.11.5/configuration.md +++ b/website/versioned_docs/version-1.11.5/configuration.md @@ -605,7 +605,7 @@ Controls whether record (structural) validation runs when Storm first encounters | `warn` | Errors are logged as warnings; startup continues. | | `none` | Record validation is skipped entirely. | -### storm.validation.schema_mode +### storm.validation.schema_mode {#schema-validation} Controls whether schema validation runs at startup (Spring Boot only; for programmatic use, see [Validation](validation.md#programmatic-api)). diff --git a/website/versioned_docs/version-1.11.5/faq.md b/website/versioned_docs/version-1.11.5/faq.md index eb6bbf037..c0d13974e 100644 --- a/website/versioned_docs/version-1.11.5/faq.md +++ b/website/versioned_docs/version-1.11.5/faq.md @@ -67,7 +67,7 @@ Storm never issues DDL statements (CREATE TABLE, ALTER TABLE, DROP TABLE). It re ### No Lazy-Loading Proxies -Storm does not use bytecode manipulation or runtime proxies to intercept field access. This eliminates `LazyInitializationException`, hidden database queries, and session-dependent entity behavior. Relationships declared with `@FK` are loaded eagerly in a single query. When you need deferred loading (for example, a rarely-accessed large sub-graph), use `Ref` to make the database access explicit and intentional. See [Entities: Deferred Loading](entities.md#deferred-loading-with-ref) for details. +Storm does not use bytecode manipulation or runtime proxies to intercept field access. This eliminates `LazyInitializationException`, hidden database queries, and session-dependent entity behavior. Relationships declared with `@FK` are loaded eagerly in a single query. When you need deferred loading (for example, a rarely-accessed large sub-graph), use `Ref` to make the database access explicit and intentional. See [Refs: Deferred Loading](refs.md#deferred-loading) for details. ### No Second-Level Cache diff --git a/website/versioned_docs/version-1.11.5/getting-started.md b/website/versioned_docs/version-1.11.5/getting-started.md index 9e45aeb15..148e04f25 100644 --- a/website/versioned_docs/version-1.11.5/getting-started.md +++ b/website/versioned_docs/version-1.11.5/getting-started.md @@ -6,7 +6,7 @@ Storm is a modern SQL Template and ORM framework for Kotlin 2.0+ and Java 21+. I Storm is built around a simple idea: your data model should be a plain value, not a framework-managed object. In Storm, entities are Kotlin data classes or Java records. They carry no hidden state, no change-tracking proxies, and no lazy-loading hooks. You can create them, pass them across layers, serialize them, compare them by value, and store them in collections without worrying about session scope, detachment, or side effects. What you see in the source code is exactly what exists at runtime. -This stateless design is a deliberate trade-off. Traditional ORMs like JPA/Hibernate give you transparent lazy loading and proxy-based dirty checking, but at the cost of complexity: you must reason about managed vs. detached state, proxy initialization, persistence context boundaries, and cascading rules that interact in subtle ways. Storm avoids all of this. It still performs [dirty checking](/dirty-checking), but by comparing entity state within a transaction rather than through proxies or bytecode manipulation. When you query a relationship, you get the result in the same query. There are no surprises. +This stateless design is a deliberate trade-off. Traditional ORMs like JPA/Hibernate give you transparent lazy loading and proxy-based dirty checking, but at the cost of complexity: you must reason about managed vs. detached state, proxy initialization, persistence context boundaries, and cascading rules that interact in subtle ways. Storm avoids all of this. It still performs [dirty checking](dirty-checking.md), but by comparing entity state within a transaction rather than through proxies or bytecode manipulation. When you query a relationship, you get the result in the same query. There are no surprises. Storm is also SQL-first. Rather than abstracting SQL away behind a query language (like JPQL) or a verbose criteria builder, Storm embraces SQL directly. Its SQL Template API lets you write real SQL with type-safe parameter interpolation and automatic result mapping. For common CRUD patterns, the type-safe DSL and repository interfaces provide concise, compiler-checked alternatives, but the full power of SQL is always available when you need it. diff --git a/website/versioned_docs/version-1.11.5/index.md b/website/versioned_docs/version-1.11.5/index.md index 2dab352ea..b891edc0f 100644 --- a/website/versioned_docs/version-1.11.5/index.md +++ b/website/versioned_docs/version-1.11.5/index.md @@ -236,7 +236,7 @@ If you are a tech lead or architect evaluating Storm for a production system, th Storm is focused on being a great ORM and SQL template engine. It intentionally does not include: -- **Schema migration or DDL generation.** Storm does not automatically create, alter, or drop tables at runtime. With Storm's [AI integration](/ai), your coding assistant can read your database schema and generate Flyway or Liquibase migration scripts on demand. For schema versioning, use [Flyway](https://flywaydb.org/) or [Liquibase](https://www.liquibase.com/). +- **Schema migration or DDL generation.** Storm does not automatically create, alter, or drop tables at runtime. With Storm's [AI integration](ai.md), your coding assistant can read your database schema and generate Flyway or Liquibase migration scripts on demand. For schema versioning, use [Flyway](https://flywaydb.org/) or [Liquibase](https://www.liquibase.com/). - **Second-level cache.** Storm's entity cache is transaction-scoped and cleared on commit. For cross-transaction caching, use Spring's `@Cacheable` or a dedicated cache layer like Caffeine or Redis. - **Lazy loading proxies.** Entities are plain records with no proxies. Related entities are loaded eagerly in a single query via JOINs. For deferred loading, use [Refs](refs.md) to explicitly control when related data is fetched. diff --git a/website/versioned_docs/version-1.11.5/relationships.md b/website/versioned_docs/version-1.11.5/relationships.md index ad891c745..2692be329 100644 --- a/website/versioned_docs/version-1.11.5/relationships.md +++ b/website/versioned_docs/version-1.11.5/relationships.md @@ -68,8 +68,8 @@ data class User( When you query a `User`, the related `City` is automatically loaded: ```kotlin -val user = orm.find(User_.id eq userId) -println(user?.city.name) // City is already loaded +val user = orm.get(User_.id eq userId) +println(user.city.name) // City is already loaded ```