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: .cursor/rules/412-frameworks-quarkus-panache.md
+14-14Lines changed: 14 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
name: 412-frameworks-quarkus-panache
3
-
description: Use when you need data access with Quarkus Hibernate ORM Panache — including PanacheEntity / PanacheEntityBase, PanacheRepository, named and HQL queries, transactions, pagination, and immutable-friendly patterns. This is the Quarkus analogue to Spring Data for relational persistence; prefer Panache APIs over verbose persistence boilerplate. For Flyway-backed DDL and versioned schema changes, use `@413-frameworks-quarkus-db-migrations-flyway`.
3
+
description: Use when you need data access with Quarkus Hibernate ORM Panache — including PanacheEntity / PanacheEntityBase, PanacheRepository, named queries, JPQL, native SQL, transactions, pagination, and immutable-friendly patterns. This is the Quarkus analogue to Spring Data for relational persistence; prefer Panache APIs over verbose persistence boilerplate. For Flyway-backed DDL and versioned schema changes, use `@413-frameworks-quarkus-db-migrations-flyway`.
4
4
license: Apache-2.0
5
5
metadata:
6
6
author: Juan Antonio Breña Moral
@@ -14,7 +14,7 @@ You are a Senior software engineer with extensive experience in Quarkus, Hiberna
14
14
15
15
## Goal
16
16
17
-
Panache simplifies Hibernate ORM in Quarkus: **active record** (`PanacheEntity`) for small entities or **repository** (`PanacheRepository`) for a cleaner separation. Prefer explicit queries (`find`, `list`, `HQL`) over magic lazy graphs; keep aggregates focused; use `@Transactional` on services. For hand-written SQL and reporting, use `@411-frameworks-quarkus-jdbc` instead of forcing everything through Panache. For schema evolution with Flyway, use `@413-frameworks-quarkus-db-migrations-flyway`.
17
+
Panache simplifies Hibernate ORM in Quarkus: **active record** (`PanacheEntity`) for small entities or **repository** (`PanacheRepository`) for a cleaner separation. Prefer explicit queries (`find`, `list`, JPQL) over magic lazy graphs; keep aggregates focused; use `@Transactional` on services. Use native queries when you want SQL you control and still stay in Hibernate (transactions, same datasource, optional entity mapping). For hand-written SQL and reporting that should bypass Hibernate at the application boundary, use `@411-frameworks-quarkus-jdbc` instead of forcing everything through Panache. For schema evolution with Flyway, use `@413-frameworks-quarkus-db-migrations-flyway`.
18
18
19
19
## Constraints
20
20
@@ -34,7 +34,7 @@ Before applying any recommendations, ensure the project is in a valid state by r
34
34
- Example 1: Active record entity
35
35
- Example 2: Panache repository
36
36
- Example 3: Service layer transaction
37
-
- Example 4: Parameterized HQL queries
37
+
- Example 4: Parameterized JPQL queries
38
38
- Example 5: DTO projections
39
39
- Example 6: Pagination
40
40
- Example 7: @NamedQuery for stable, reused queries
@@ -109,7 +109,7 @@ public class BookRepository implements PanacheRepository<Book> {
109
109
110
110
publicList<Book>search(StringuserFragment) {
111
111
return list("FROM Book WHERE title LIKE '"+ userFragment +"%'");
112
-
// injection risk — never concatenate user input into HQL
112
+
// injection risk — never concatenate user input into JPQL
113
113
}
114
114
}
115
115
```
@@ -159,10 +159,10 @@ public void publish(@PathParam("id") long id) {
159
159
}
160
160
```
161
161
162
-
### Example 4: Parameterized HQL queries
162
+
### Example 4: Parameterized JPQL queries
163
163
164
164
Title: Positional and named parameters; firstResultOptional for single rows
165
-
Description: Panache offers three levels of query syntax: field shorthand for simple equality, positional `?1` parameters, and full HQL with `Parameters.with(...)` for named bindings. Use `firstResultOptional()` for single-row lookups rather than `findById` when querying by non-PK columns. Never concatenate user input into query strings.
165
+
Description: Panache offers three levels of query syntax: field shorthand for simple equality, positional `?1` parameters, and full JPQL with `Parameters.with(...)` for named bindings. Use `firstResultOptional()` for single-row lookups rather than `findById` when querying by non-PK columns. Never concatenate user input into query strings.
// Bad: HQL injection risk — never build query strings from user input
209
+
// Bad: query injection risk — never build query strings from user input
210
210
return find("FROM Book WHERE author LIKE '%"+ fragment +"%'").list();
211
211
}
212
212
}
@@ -335,7 +335,7 @@ public class BookRepository implements PanacheRepository<Book> {
335
335
### Example 7: @NamedQuery for stable, reused queries
336
336
337
337
Title: Declare on the entity; invoke with # prefix; validated at startup
338
-
Description: `@NamedQuery` declarations are parsed and validated by Hibernate at application startup, catching HQL errors early. Use them for frequently executed, stable queries to enable Hibernate's query plan caching and to centralise SQL intent near the entity it queries.
338
+
Description: `@NamedQuery` declarations are parsed and validated by Hibernate at application startup, catching query parse errors early. Use them for frequently executed, stable queries to enable Hibernate's query plan caching and to centralise SQL intent near the entity it queries.
return find("FROM Book WHERE genre = ?1 AND plblished = true ORDER BY title", genre).list();
@@ -392,8 +392,8 @@ public class BookRepository implements PanacheRepository<Book> {
392
392
393
393
### Example 8: JOIN FETCH to avoid N+1 queries
394
394
395
-
Title: Eagerly load associations in one HQL query instead of triggering lazy loads per entity
396
-
Description: When a use case iterates a collection association on every returned entity, issuing N individual `SELECT` statements. Use `JOIN FETCH` in HQL to load the association in the same query. Outside of an open Hibernate session (e.g. serializing to JSON), lazy access throws `LazyInitializationException`.
395
+
Title: Eagerly load associations in one JPQL query instead of triggering lazy loads per entity
396
+
Description: When a use case iterates a collection association on every returned entity, issuing N individual `SELECT` statements. Use `JOIN FETCH` in JPQL to load the association in the same query. Outside of an open Hibernate session (e.g. serializing to JSON), lazy access throws `LazyInitializationException`.
397
397
398
398
**Good example:**
399
399
@@ -614,7 +614,7 @@ class BookRepositoryTest {
614
614
615
615
## Output Format
616
616
617
-
-**ANALYZE** entities, repositories, and services for HQL injection risk, leaky entity boundaries, missing `@Transactional`, unbounded list queries, lazy N+1 patterns, missing `@Version`, and absence of test isolation
617
+
-**ANALYZE** entities, repositories, and services for query injection risk, leaky entity boundaries, missing `@Transactional`, unbounded list queries, lazy N+1 patterns, missing `@Version`, and absence of test isolation
618
618
-**CATEGORIZE** findings by impact (SECURITY for query injection, CORRECTNESS for missing transactions or N+1, PERFORMANCE for unbounded queries or missing pagination, MAINTAINABILITY for entity exposure at API boundaries)
619
619
-**APPLY** improvements: introduce parameterized queries, `project(Class)` DTO projections, `page(Page.of(...))` pagination, `@NamedQuery` for stable queries, `JOIN FETCH` for needed associations, `@Version` for concurrency control
620
620
-**IMPLEMENT** changes consistently: keep entity, service, and REST resource layers coherent; update test fixtures when entity shape changes
@@ -626,10 +626,10 @@ class BookRepositoryTest {
626
626
627
627
-**BLOCKING SAFETY CHECK**: ALWAYS run `./mvnw compile` before ANY Panache refactoring — compilation failure is a HARD STOP
628
628
-**CRITICAL VALIDATION**: Run `./mvnw clean verify` after changes; confirm persistence tests pass with Dev Services before promoting
629
-
-**QUERY SAFETY**: Never concatenate user input into HQL, PanacheQL, or native SQL — use `?1`, `:name`, or `Parameters.with(...)` exclusively
629
+
-**QUERY SAFETY**: Never concatenate user input into JPQL, PanacheQL, or native SQL — use `?1`, `:name`, or `Parameters.with(...)` exclusively
630
630
-**ENTITY BOUNDARIES**: Do not return managed entities directly from REST resources — map to DTOs or use `project(Class)` to keep API contracts stable and prevent accidental field exposure
631
631
-**PAGINATION**: Never call `listAll()` or an unbound `list(query)` on production tables — always apply `.page(Page.of(index, size))` or a LIMIT clause
632
-
-**N+1 PREVENTION**: When a use case accesses collection associations on every returned entity, add `JOIN FETCH` to the HQL query; lazy access outside a Hibernate session throws `LazyInitializationException`
632
+
-**N+1 PREVENTION**: When a use case accesses collection associations on every returned entity, add `JOIN FETCH` to the JPQL query; lazy access outside a Hibernate session throws `LazyInitializationException`
633
633
-**OPTIMISTIC LOCKING**: Adding `@Version` to an existing entity requires a `version` column in the schema — apply via a migration (`@413-frameworks-quarkus-db-migrations-flyway`) before deploying; mismatched schema causes startup failure
634
634
-**CDI SELF-INVOCATION**: Never call a `@Transactional` method via `this.method()` within the same CDI bean — the interceptor is bypassed; extract to a separate injected bean
635
635
-**INCREMENTAL SAFETY**: Change one entity, repository, or service at a time; verify with `@QuarkusTest` + `@TestTransaction` between steps; do not combine aggregate boundary changes with query refactoring in one commit
Copy file name to clipboardExpand all lines: skills-generator/src/main/resources/skills/412-skill.xml
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@
7
7
<version>0.13.0</version>
8
8
<license>Apache-2.0</license>
9
9
<description><![CDATA[
10
-
Use when you need data access with Quarkus Hibernate ORM Panache — including PanacheEntity / PanacheEntityBase, PanacheRepository, named and HQL queries, DTO projections (project(Class)), pagination (Page.of()), N+1 avoidance (JOIN FETCH), optimistic locking (@Version / OptimisticLockException), @NamedQuery for validated reusable queries, transactions, @TestTransaction for test isolation, and immutable-friendly patterns. This is the Quarkus analogue to Spring Data for relational persistence.
10
+
Use when you need data access with Quarkus Hibernate ORM Panache — including PanacheEntity / PanacheEntityBase, PanacheRepository, named queries, JPQL, native SQL, DTO projections (project(Class)), pagination (Page.of()), N+1 avoidance (JOIN FETCH), optimistic locking (@Version / OptimisticLockException), @NamedQuery for validated reusable queries, transactions, @TestTransaction for test isolation, and immutable-friendly patterns. This is the Quarkus analogue to Spring Data for relational persistence.
11
11
]]>
12
12
</description>
13
13
</metadata>
@@ -19,16 +19,16 @@ Apply Panache patterns for Hibernate ORM in Quarkus.
19
19
**What is covered in this Skill?**
20
20
21
21
- Active record (PanacheEntity) vs PanacheRepository — when to use each
22
-
- Parameterized HQL / Panache queries: positional (?1) and named (:param) — no unsafe concatenation
22
+
- Parameterized JPQL / Panache queries: positional (?1) and named (:param) — no unsafe concatenation
23
23
- @NamedQuery on entities for reusable, build-time validated queries
24
24
- DTO projections with project(Class) to avoid exposing managed entities
25
25
- Pagination with Page.of(pageIndex, pageSize) and query.count()
26
-
- N+1 avoidance with JOIN FETCH in HQL queries
26
+
- N+1 avoidance with JOIN FETCH in JPQL queries
27
27
- Optimistic locking with @Version and handling OptimisticLockException
28
28
- @Transactional application services
29
29
- @TestTransaction for automatic rollback in @QuarkusTest tests
30
30
- Mapping entities vs exposing DTOs at REST boundaries
31
-
- Pairing with `@411` for raw SQL when needed
31
+
- Native queries via Hibernate when you want controlled SQL in the same transaction; pairing with `@411` for JDBC when bypassing Hibernate at the boundary
32
32
33
33
**Scope:** Apply recommendations based on the reference rules and good/bad code examples.
Copy file name to clipboardExpand all lines: skills/412-frameworks-quarkus-panache/SKILL.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
name: 412-frameworks-quarkus-panache
3
-
description: Use when you need data access with Quarkus Hibernate ORM Panache — including PanacheEntity / PanacheEntityBase, PanacheRepository, named and HQL queries, DTO projections (project(Class)), pagination (Page.of()), N+1 avoidance (JOIN FETCH), optimistic locking (@Version / OptimisticLockException), @NamedQuery for validated reusable queries, transactions, @TestTransaction for test isolation, and immutable-friendly patterns. This is the Quarkus analogue to Spring Data for relational persistence. Part of the skills-for-java project
3
+
description: Use when you need data access with Quarkus Hibernate ORM Panache — including PanacheEntity / PanacheEntityBase, PanacheRepository, named queries, JPQL, native SQL, DTO projections (project(Class)), pagination (Page.of()), N+1 avoidance (JOIN FETCH), optimistic locking (@Version / OptimisticLockException), @NamedQuery for validated reusable queries, transactions, @TestTransaction for test isolation, and immutable-friendly patterns. This is the Quarkus analogue to Spring Data for relational persistence. Part of the skills-for-java project
4
4
license: Apache-2.0
5
5
metadata:
6
6
author: Juan Antonio Breña Moral
@@ -13,16 +13,16 @@ Apply Panache patterns for Hibernate ORM in Quarkus.
13
13
**What is covered in this Skill?**
14
14
15
15
- Active record (PanacheEntity) vs PanacheRepository — when to use each
16
-
- Parameterized HQL / Panache queries: positional (?1) and named (:param) — no unsafe concatenation
16
+
- Parameterized JPQL / Panache queries: positional (?1) and named (:param) — no unsafe concatenation
17
17
-@NamedQuery on entities for reusable, build-time validated queries
18
18
- DTO projections with project(Class) to avoid exposing managed entities
19
19
- Pagination with Page.of(pageIndex, pageSize) and query.count()
20
-
- N+1 avoidance with JOIN FETCH in HQL queries
20
+
- N+1 avoidance with JOIN FETCH in JPQL queries
21
21
- Optimistic locking with @Version and handling OptimisticLockException
22
22
-@Transactional application services
23
23
-@TestTransaction for automatic rollback in @QuarkusTest tests
24
24
- Mapping entities vs exposing DTOs at REST boundaries
25
-
-Pairing with `@411` for raw SQL when needed
25
+
-Native queries via Hibernate when you want controlled SQL in the same transaction; pairing with `@411` for JDBC when bypassing Hibernate at the boundary
26
26
27
27
**Scope:** Apply recommendations based on the reference rules and good/bad code examples.
0 commit comments