Helidon Data JDBC - implementation of declarative and imperative APIs - #12232
Helidon Data JDBC - implementation of declarative and imperative APIs#12232bhatpmk wants to merge 48 commits into
Conversation
| .build())); | ||
| plan.method().throwsChecked().forEach(method::addThrows); | ||
| for (TypeName txAnnotation : JdbcPersistenceTypes.TX_ANNOTATIONS) { | ||
| plan.method().findAnnotation(txAnnotation).ifPresent(method::addAnnotation); |
There was a problem hiding this comment.
AI finding: Type-level transaction annotations are lost here. Tx.* annotations target both types and methods and are source-retained, but this code copies only annotations declared directly on repository methods. The generated class does not copy the repository type annotation either. Consequently, @Tx.Required interface Repository generates methods without the requested transaction interceptor. Resolve the effective type- and method-level transaction annotation, with method-level precedence, and add coverage for type-level use.
There was a problem hiding this comment.
Updated io.helidon.data.codegen.common.BasePersistenceGenerator to retain transaction annotations declarated at the type-level. The change doesn't resolve precedence or conflicting annotations. The change will also affect the JPA based implementation.
916a1ed to
22eca82
Compare
bhatpmk
left a comment
There was a problem hiding this comment.
I have consolidated response to the review comments together.
| * @param start first dash offset | ||
| * @return whether the two dashes begin a protected line comment | ||
| */ | ||
| boolean lineComment(String source, int start) { |
There was a problem hiding this comment.
This is an intentional portability boundary. PostgreSQL treats every -- sequence as a line-comment opener, while MySQL requires whitespace or a control character after the second dash. Treating every occurrence as a comment would hide a real bind marker in valid MySQL expressions such as balance--?. The portable profile therefore requires whitespace, a control character, or end-of-input. PostgreSQL SQL processed by JdbcClient must consequently use conventional spacing such as -- comment. Supporting the broader PostgreSQL rule will be done with a database profile, in future.
| * @param start first dash offset | ||
| * @return whether the two dashes begin a protected line comment | ||
| */ | ||
| private boolean lineComment(String source, int start) { |
There was a problem hiding this comment.
This rule intentionally mirrors the runtime JDBC marker policy. Code generation rewrites named markers while runtime code counts positional markers, so the two implementations must classify line comments identically. Otherwise, a generated repository can validate one parameter plan and execute another. The portable whitespace requirement preserves markers for databases with MySQL style double-dash semantics. PostgreSQL SQL should use -- comment until an explicitly selected PostgreSQL profile is available.
tomas-langer
left a comment
There was a problem hiding this comment.
AI Review: Review findings are included in the inline comments.
| * rule explicit and is verified against the runtime scanner's conformance | ||
| * corpus. | ||
| */ | ||
| final class JdbcSqlMarkerLexer { |
There was a problem hiding this comment.
Naïvely I would think that SQL lexing would be useful outside of code generation.
There was a problem hiding this comment.
Addressed. The general SQL lexical recognition is extracted to data/jdbc/lexical module. Updated JDBC codegen and runtime code to use the new module.
| /** | ||
| * Compile-time correspondence between repository parameters and JDBC positions. | ||
| */ | ||
| record JdbcSqlParameterPlan(String sql, List<Bind> binds) { |
There was a problem hiding this comment.
This seems like a lot of ceremony for what should be a fairly simple operation. I would also expect named parameter support to work at runtime.
There was a problem hiding this comment.
The general SQL marker recognition is removed from this class to the shared JDBC lexical module. The remaining plan is specific to codegen. Named parameters work declarative repositories, as codegen rewrites them to positional JDBC SQL and generates corresponding binds.
| /** | ||
| * Resolves repository methods and generic types across an interface hierarchy. | ||
| */ | ||
| final class JdbcTypeHierarchy { |
There was a problem hiding this comment.
This class seems to recapitulate whole swaths of javax.lang.model.util.Types and implement a good chunk of the Java Language Specification. Was that its intent? It surprises me naïvely that this would be necessary.
There was a problem hiding this comment.
The intent was to resolve effective inherited repository methods. Correctly supporting inheritance caused the implementation to reproduce a substantial portion of Types and Java language specification.
The provider-neutral operations are now moved to an internal TypeHierarchyResolver in the common codegen module. The JDBC repository method discovery and explicit RowMapper contract resolution now use TypeHierarchyResolver.
…erative API to create JdbcClient
…on fails and other review comments
… independently, preventing timezone conversion errors from canceling during round-trip assertions
…don Data JDBC scalar types
…JDBC driver class name in ConnectionConfig
488e6a8 to
0f1278d
Compare
Resolves #11711
Resolves #11712
Resolves #11713
Description
Adds a Helidon Data provider built directly on Java SE JDBC. It supports compile-time generated declarative repositories and a public imperative JdbcClient API without depending on Jakarta Persistence.
Declarative repositories
Parameter binding
Result mapping
Updates and generated keys
Imperative JDBC API
Local transactions
behavior applies to both JDBC and Jakarta Persistence generated repositories. Type-level repository transaction annotations have limited preview behavior; applications should apply one transaction
annotation directly to each repository method that requires transaction propagation.
Portable SQL profile
Imperative and generated repositories use the same portable marker-recognition policy so code generation and runtime binding produce consistent parameter plans.
The portable profile protects standard quoted strings and identifiers, MySQL backtick identifiers, conventional comments, PostgreSQL escape and dollar-quoted strings, and Oracle alternative-quoted
strings when their complete delimiters are recognized.
The profile intentionally does not implement a complete database dialect:
Database-specific profiles are not configurable in this release.
Documentation
This is a new feature and #12231 will provide the documentation.