Support "RETURNING INTO" clause for INSERT/UPDATE/DELETE in Oracle database#3669
Open
radovanradic wants to merge 32 commits into5.0.xfrom
Open
Support "RETURNING INTO" clause for INSERT/UPDATE/DELETE in Oracle database#3669radovanradic wants to merge 32 commits into5.0.xfrom
radovanradic wants to merge 32 commits into5.0.xfrom
Conversation
dstepanov
reviewed
Jan 16, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Adds support for Oracle RETURNING ... INTO semantics across INSERT/UPDATE/DELETE by propagating OUT parameter metadata from query building/processing into runtime JDBC execution.
Changes:
- Introduces builder-time and runtime
QueryOutParameterBindingmetadata and wires it through annotation processing (DataMethodQueryOutParameter) intoStoredQuery. - Updates SQL builders and raw
@Queryparsing to generate Oracle PL/SQL blocks (BEGIN ... RETURNING ... INTO ...; END;) and capture OUT parameter ordering/types. - Extends JDBC operations to execute Oracle returning statements via
CallableStatementand map OUT parameters back to entities / scalar results, with new tests.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| data-runtime/.../QueryResultStoredQuery.java | Adds runtime OUT parameter bindings mapped from builder metadata. |
| data-runtime/.../DelegateStoredQuery.java | Delegates new getOutParameterBindings() API. |
| data-runtime/.../DefaultStoredQuery.java | Reads OUT parameter metadata from generated annotations. |
| data-runtime/.../DefaultSqlStoredQuery.java | Pass-through for OUT parameter bindings. |
| data-processor/.../RawQueryMethodMatcher.java | Parses Oracle RETURNING in raw queries and synthesizes OUT bindings/PLSQL wrapper. |
| data-processor/.../RepositoryTypeElementVisitor.java | Emits DataMethodQueryOutParameter annotations based on QueryResult OUT bindings. |
| data-model/.../StoredQuery.java | Adds new getOutParameterBindings() default API. |
| data-model/.../QueryResult.java | Supports OUT bindings on QueryResult with new factory overload. |
| data-model/.../sql/SqlQueryBuilder.java | Emits Oracle RETURNING ... INTO for INSERT and collects OUT binding metadata. |
| data-model/.../sql/AbstractSqlLikeQueryBuilder.java | Adds RETURNING visitor plumbing and Oracle RETURNING handling for UPDATE/DELETE. |
| data-jdbc/.../DefaultJdbcRepositoryOperations.java | Executes Oracle returning via CallableStatement and maps OUT params to entities/scalars. |
| data-jdbc/.../ColumnNameByIndexCallableResultReader.java | Adds name-based OUT param reader backed by index mapping. |
| data-processor tests + data-jdbc tests | Adds compilation/runtime regression tests for Oracle RETURNING behavior. |
| config/checkstyle/custom-suppressions.xml | Suppresses file length for SqlQueryBuilder. |
Comment on lines
+315
to
+322
| String cleanLower = SQL_COMMENT_PATTERN.matcher(finalQueryString).replaceAll("").trim().toLowerCase(Locale.ENGLISH); | ||
| boolean hasReturning = RETURNING_PATTERN.matcher(cleanLower).find(); | ||
| if (hasReturning) { | ||
| Dialect dialect = matchContext.getRepositoryClass().enumValue(Repository.class, "dialect", Dialect.class) | ||
| .orElse(Dialect.ANSI); | ||
| if (dialect == Dialect.ORACLE) { | ||
| SourcePersistentEntity entity = persistentEntity != null ? persistentEntity : matchContext.getRootEntity(); | ||
| int returningIdx = cleanLower.lastIndexOf("returning"); |
Comment on lines
+488
to
+489
| } | ||
| return QueryResult.of("", queryParts, parameterBindings, outBindings, Map.of()); |
| .orElse(identity.getAnnotationMetadata().stringValue(JSON_PROPERTY_ANNOTATION) | ||
| .orElse(identity.getName())); | ||
| resultColumns.add(identityName); | ||
| resultColumnTypes.add(identity.getDataType()); |
Comment on lines
+699
to
+704
| if (StringUtils.isNotEmpty(b.getName())) { | ||
| outBuilder.member(DataMethodQueryOutParameter.META_MEMBER_NAME, b.getName()); | ||
| } | ||
| if (b.getDataType() != null) { | ||
| outBuilder.member(DataMethodQueryOutParameter.META_MEMBER_DATA_TYPE, b.getDataType()); | ||
| } |
| boolean isEntityResult = preparedQuery.getResultDataType() == DataType.ENTITY; | ||
| if (isEntityResult) { | ||
| SqlResultEntityTypeMapper mapper = getSqlResultEntityTypeMapper(preparedQuery.getPersistentEntity(), columnNames, inCount); | ||
| return List.of((R) mapper.readEntity(cs)); |
|
|
||
| <suppressions> | ||
| <suppress checks="FileLength" files=".*AbstractSqlLikeQueryBuilder.*" /> | ||
| <suppress checks="FileLength" files="SqlQueryBuilder.java" /> |
Comment on lines
+207
to
+217
| public String name() { | ||
| return delegate.getName(); | ||
| } | ||
|
|
||
| @Override | ||
| public DataType dataType() { | ||
| return delegate.getDataType(); | ||
| } | ||
|
|
||
| } | ||
|
|
Contributor
Author
|
@copilot open a new pull request to apply changes based on the comments in this thread |
7 tasks
Contributor
|
@radovanradic I've opened a new pull request, #3762, to work on those changes. Once the pull request is ready, I'll request review from you. |
* Initial plan * Apply PR review feedback for Oracle RETURNING INTO support Co-authored-by: radovanradic <10271067+radovanradic@users.noreply.github.com> * Use DEFAULT_POSITIONAL_PARAMETER_MARKER constant and clarify assembledSql comment Co-authored-by: radovanradic <10271067+radovanradic@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: radovanradic <10271067+radovanradic@users.noreply.github.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Implementation for issue #2669