spring-projects/spring-data-relational
57.4
Adequate · 22 September 2026
56.9k
lines of production code
Java
primary language
7
measurements over time
What this system is
This system is the Spring Data Relational framework, providing data access abstractions for both synchronous JDBC and reactive R2DBC connections. It enables developers to persist domain aggregates through repository interfaces, derived query methods, and a fluent Criteria API, while supporting advanced features like composite keys, upserts, and schema generation via Liquibase. The framework is heavily optimized for modern deployment targets, featuring comprehensive Ahead-of-Time (AOT) compilation support for native images and seamless integration with Kotlin coroutines.
How it got here
2017–2018 — Core architecture refactoring and MyBatis integration
30 changes.
This period focused on a comprehensive restructuring of the Spring Data JDBC core to improve modularity, performance, and maintainability. Key developments included introducing dedicated executor and context classes, enhancing mapping abstractions for aggregate references, and adding support for MyBatis as an underlying data access technology. The work also established robust infrastructure for query derivation, batching, and lifecycle events, accompanied by extensive test coverage across multiple database platforms.
2019–2022 — SQL DSL and AOT modernization
52 changes.
This period focused on replacing the SQL generation layer with a new modular DSL and visitor-based rendering engine, enabling advanced features like upserts and window functions. It also introduced Ahead-of-Time (AOT) compilation support across JDBC, Relational, and R2DBC modules to improve native image compatibility, alongside significant refactoring of R2DBC's reactive repository and mapping infrastructure.
2023–2026 — SQL generation and schema management infrastructure
22 changes.
This period focused on building core infrastructure for efficient single-query aggregate loading and Liquibase-based schema generation in Spring Data JDBC. Significant work included implementing the SQL generation engine with alias management, adding hierarchical data support, and introducing Ahead-of-Time compilation for repositories to improve native image compatibility. The effort was heavily supported by comprehensive unit tests, JMH benchmarks, and CI environment improvements to ensure reliability and performance.
Features
Add Ahead-of-Time (AOT) runtime hints for R2DBC repositories
Users running R2DBC-based applications with Spring AOT (e.g., for native images) now benefit from automatic registration of reflection hints. A new \R2dbcRuntimeHints\ class registers necessary reflection access for \SimpleR2dbcRepository\ and key mapping callbacks (\AfterConvertCallback\, \BeforeSaveCallback\, etc.), as well as simple types from the PostgreSQL dialect, ensuring these components are available at runtime without manual configuration.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/aot · high confidence
Add ArrayUtils helper and JSpecify nullability annotations
This change introduces a new ArrayUtils utility class in the R2DBC support package, providing methods to determine array dimension depth and create empty arrays of specific dimensions. Additionally, the package-info.java file now includes JSpecify annotations (@NullMarked) to enforce nullability constraints across the support infrastructure.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/support · high confidence
Add support for custom BeanNameGenerator in @EnableR2dbcRepositories
The @EnableR2dbcRepositories annotation now exposes a nameGenerator attribute, allowing users to configure a specific BeanNameGenerator to control how repository beans are named during component scanning. This change is implemented via the new EnableR2dbcRepositories annotation, the R2dbcRepositoriesRegistrar, and the R2dbcRepositoryConfigurationExtension, which together wire the custom generator into the R2DBC repository infrastructure.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/repository/config · high confidence
Add support for disabling entity lifecycle events
A new \EntityLifecycleEventDelegate\ class has been introduced to manage the publishing of entity lifecycle events. This component allows users to disable event publishing entirely via a configuration flag, providing control over when lifecycle events are triggered and published to the application context.
spring-data-relational/src/main/java/org/springframework/data/relational/core · high confidence
Added AOT runtime hints for JDBC and Postgres support
A new JdbcRuntimeHints class has been introduced to register reflection and proxy hints required for Ahead-of-Time (AOT) compilation. This ensures that key JDBC components, including SimpleJdbcRepository, various relational callbacks (such as BeforeSave and AfterConvert), and auditing callbacks, are properly registered for reflection. Additionally, it registers JDK proxies for RelationResolver and ensures that Postgres-specific types, including TypeInfoCache and simple types from JdbcPostgresDialect, are accessible at runtime, facilitating better native image compatibility.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/aot · high confidence
Added AOT support for RelationalManagedTypes
A new AOT factory file registers the RelationalManagedTypesBeanRegistrationAotProcessor, enabling ahead-of-time processing for relational managed types in Spring Data Relational applications.
spring-data-relational/src/main/resources · high confidence
Added JMH benchmarks for composite ID operations
New JMH benchmark classes have been added to the Spring Data JDBC project to measure performance of composite ID handling. The \BenchmarkSettings\ class provides global configuration for warmup, measurement, and throughput modes, while \CompositeIdBenchmarks\ specifically tests operations such as inserting, loading, saving, updating, and deleting entities with composite or embedded primary keys using an embedded HSQL database.
spring-data-jdbc/src/jmh · high confidence
Added Kotlin infix extension functions for Criteria queries
New Kotlin extension functions have been added to the \Criteria\ API to improve syntax readability. Users can now use the \isEqual\ infix function for equality checks and \isIn\ functions for collection-based inclusion checks, providing more idiomatic Kotlin alternatives to the existing \is\ and \in\ methods.
spring-data-relational/src/main/kotlin · high confidence
Added RelationalAuditingCallback for entity auditing
A new RelationalAuditingCallback class has been introduced in the Spring Data Relational auditing package. This component implements the BeforeConvertCallback interface to automatically capture and mark auditing information (such as creation and modification timestamps) on entities before they are persisted or updated. It integrates with the existing IsNewAwareAuditingHandler and is designed to run with a specific order priority to ensure it executes before other listeners.
spring-data-relational/src/main/java/org/springframework/data/relational/auditing · high confidence
Adds AOT support and dynamic dialect detection for Spring Data JDBC
Spring Data JDBC now supports Ahead-of-Time (AOT) compilation by registering runtime hints via the new \aot.factories\ file, enabling better performance and native image compatibility. Additionally, the module introduces dynamic database dialect detection through a new \DialectResolver\ provider, allowing the framework to automatically adapt to the underlying JDBC driver without manual configuration.
spring-data-jdbc/src/main/resources · high confidence
Ahead-of-Time (AOT) generation support for Spring Data JDBC repositories
Spring Data JDBC now supports Ahead-of-Time (AOT) compilation for repository query methods. This change introduces a new \aot\ package containing a \JdbcRepositoryContributor\ that generates optimized, pre-compiled repository fragments at build time. The implementation includes classes for managing query metadata (\AotQueries\, \AotQuery\), constructing SQL code blocks (\JdbcCodeBlocks\), and handling parameter binding and placeholder processing (\PlaceholderAccessor\, \QueriesFactory\). This enables faster startup times and reduced memory footprint for applications using native image tools like GraalVM, as repository queries are resolved and compiled during the build phase rather than at runtime.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/aot · high confidence
Ahead-of-Time support for RelationalManagedTypes
Spring Data Relational now includes Ahead-of-Time (AOT) processing support for relational managed types. A new \RelationalManagedTypes\ class wraps the standard \ManagedTypes\ interface to handle relational-specific type metadata, and a corresponding \RelationalManagedTypesBeanRegistrationAotProcessor\ ensures these beans are correctly registered during AOT compilation. This enables better compatibility with native image builds by ensuring relational type information is available at build time.
spring-data-relational/src/main/java/org/springframework/data/relational/aot · high confidence
Enable Ahead-of-Time (AOT) hints for R2DBC repositories
Users can now benefit from improved startup performance and reduced memory footprint in native images, as the module registers specific runtime hints for R2DBC repositories via the Spring AOT framework.
spring-data-r2dbc/src/main/resources · high confidence
Introduce AggregatePath for structured aggregate navigation
The mapping layer now includes an AggregatePath abstraction (along with DefaultAggregatePath, traversal utilities, and table/column info builders) to represent and navigate paths within a relational aggregate from the root. This provides structured, cacheable path handling for deriving table aliases, column information, and identifier ownership, enabling more consistent mapping of complex embedded and collection relationships.
spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping · high confidence
Introduce query derivation and Query by Example support for relational repositories
This change adds the infrastructure for deriving SQL queries from repository method names (e.g., \findByLastnameAndAge\) and introduces Query by Example support. It introduces new classes in the \repository.query\ package, including \CriteriaFactory\ to map method name parts to query criteria, \RelationalQueryCreator\ to build queries from method signatures, and \RelationalExampleMapper\ to transform \Example\ objects into queries. This enables users to perform complex filtering and searches without writing explicit SQL or \@Query\ annotations.
spring-data-relational/src/main/java/org/springframework/data/relational/repository/query · high confidence
Introduces new Query, Criteria, and Update API objects
Spring Data Relational now provides dedicated, immutable, fluent API classes for constructing database operations. The new \Criteria\ class allows building complex, composable WHERE predicates (supporting AND/OR grouping, case-insensitivity, and operators like BETWEEN and NOT LIKE), while the \Query\ class centralizes query definition by combining criteria with column selection, sorting, and pagination (limit/offset). Additionally, the \Update\ class offers a fluent way to define SET assignments for updates, and \ValueFunction\ enables deferred value retrieval with escaping. These objects replace ad-hoc query construction, providing a structured, type-safe foundation for relational data access.
spring-data-relational/src/main/java/org/springframework/data/relational/core/query · high confidence
MyBatis integration support for Spring Data JDBC
Spring Data JDBC now supports using MyBatis as the underlying data access technology. This change introduces a new \MyBatisDataAccessStrategy\ implementation that maps operations to MyBatis statements, allowing users to leverage existing MyBatis XML mappings or annotations for their repository queries. The integration includes a \MyBatisContext\ to pass entity identifiers and instances to statements, and a \NamespaceStrategy\ to customize how MyBatis namespaces are derived from domain types. Users can combine this with the default strategy via \createCombinedAccessStrategy\ to prioritize MyBatis-defined queries while falling back to standard Spring Data JDBC behavior.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis · high confidence
New @Lock annotation for specifying SQL lock modes in repository queries
A new @Lock annotation has been added to the relational module, allowing developers to explicitly define the SQL lock mode (via LockMode) for repository query methods. This enables fine-grained control over database locking behavior directly on query definitions.
spring-data-relational/src/main/java/org/springframework/data/relational/repository · high confidence
New JDBC utility for type mapping and nullability annotations
The \spring-data-jdbc/support\ package now includes a new \JdbcUtil\ class that provides a mapping from Java classes to JDBC \SQLType\ values (such as \JDBCType.VARCHAR\ or \TIMESTAMP\_WITH\_TIMEZONE\), enabling more precise type handling when binding values to prepared statements. Additionally, the package-level \package-info.java\ has been added to apply JSpecify \@NullMarked\ annotations, standardizing nullability constraints across this support module.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/support · high confidence
New JDBC-specific dialect implementations and array support
The dialect layer now provides dedicated JDBC dialect classes (e.g., JdbcPostgresDialect, JdbcMySqlDialect, JdbcSqlServerDialect) that extend the core relational dialects to register JDBC-specific converters and array handling. This introduces native support for database array types via the new JdbcArrayColumns interface and CustomSQLType, enabling features like Postgres UUID arrays and proper SQL type representation for floats in Postgres arrays. Additionally, the JdbcSqlServerDialect now includes converters for microsoft.sql.DateTimeOffset, and the DialectResolver has been updated to use SpringFactoriesLoader for extensible dialect discovery while maintaining backward compatibility with legacy detectors.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect · high confidence
New Kotlin coroutine extensions for R2DBC operations
Added Kotlin extension functions for Spring Data R2DBC's reactive operations (select, insert, update, delete) to simplify usage with Kotlin coroutines. These extensions provide reified type parameters for cleaner API calls (e.g., \select\<T\>()\) and suspend functions that bridge reactive streams to coroutines using \awaitSingle\ and \asFlow\, enabling direct integration with Kotlin's coroutine model for database interactions.
spring-data-r2dbc/src/main/kotlin · high confidence
New Liquibase-based schema generation with foreign key support
Spring Data JDBC now includes a new schema generation module in \org.springframework.data.jdbc.core.mapping.schema\ that integrates with Liquibase to create and update database schemas. This addition introduces model classes for tables, columns, and foreign keys, along with a \LiquibaseChangeSetWriter\ that generates Liquibase change sets from entity mappings. The system supports automatic creation of foreign keys between aggregates and allows customization of SQL type mappings via the \SqlTypeMapping\ interface. Users can now manage database schema evolution through Liquibase change logs generated from their Spring Data entities.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema · high confidence
New R2DBC dialect abstraction and auto-configuration
The R2DBC module now introduces a dedicated \R2dbcDialect\ interface and a \DialectResolver\ that automatically detects the database type from the \ConnectionFactory\ metadata (H2, MySQL, PostgreSQL, Oracle, SQL Server) and applies database-specific behaviors such as bind marker styles, array support, and type converters. This change provides a unified dialect layer for R2DBC operations, ensuring correct SQL generation and type handling for each supported database without manual configuration.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect · high confidence
New SQL generation infrastructure for single-query aggregate loading
This change introduces the core SQL generation components in the \sqlgeneration\ package to support loading complete aggregates via a single SQL statement. It adds the \SqlGenerator\ interface, which defines the contract for generating \findAll\ queries with optional conditions, and the \AliasFactory\ class, which manages unique aliases for columns, tables, row numbers, and back-references to ensure generated SQL is clean and unambiguous. The \SingleQuerySqlGenerator\ implementation uses these utilities to construct complex SELECT statements with inline queries and window functions, enabling efficient retrieval of root entities and their associated collections in one round-trip.
spring-data-relational/src/main/java/org/springframework/data/relational/core/sqlgeneration · high confidence
New domain classes for hierarchical data and unsafe SQL sorting
The \spring-data-relational\ module now includes two new domain classes: \RowDocument\ and \SqlSort\. \RowDocument\ provides a tabular structure that implements \Map\<String, Object\>\ to enable hierarchical traversal of SQL results, supporting nested retrieval via \getDocument()\, \getMap()\, and \getList()\. \SqlSort\ extends \Sort\ to support 'unsafe' sort expressions that are included in queries as-is, allowing for arbitrary SQL expressions in ORDER BY clauses while requiring user-side sanitization to prevent SQL injection. These classes are available since version 3.1 (SqlSort) and 3.2 (RowDocument).
spring-data-relational/src/main/java/org/springframework/data/relational/domain · high confidence
New reactive entity callback interfaces and auditing support
This change introduces a new set of reactive entity callback interfaces in the R2DBC mapping event package, allowing users to intercept and modify domain objects at specific stages of the persistence lifecycle. Specifically, it adds BeforeConvertCallback and BeforeSaveCallback to modify entities or outbound rows before they are persisted, and AfterConvertCallback and AfterSaveCallback to process entities after they are read from or saved to the database. Additionally, a ReactiveAuditingEntityCallback is provided to automatically populate auditing fields on entities before conversion, integrating with the existing Spring Data auditing infrastructure.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/mapping/event · high confidence
Repository initialization and documentation structure update
The repository has been initialized with a new documentation structure, replacing the previous README.md with a comprehensive README.adoc that covers both JDBC and R2DBC getting started guides. New documentation files have been added, including CONTRIBUTING.adoc, SECURITY.adoc (detailing vulnerability reporting and JAR signing), CI.adoc (explaining local CI execution), and LICENSE.txt. Additionally, the Maven wrapper scripts (mvnw, mvnw.cmd) and a lombok.config have been added to standardize the build environment, while the .gitignore has been updated to exclude build artifacts and license acceptance files.
(repo-wide) · high confidence
Support for custom RowMapper and ResultSetExtractor beans in JDBC repositories
Users can now configure custom Spring beans for mapping database results to entities by specifying a \rowMapperRef\ or \resultSetExtractorRef\ in \@EnableJdbcRepositories\. The repository infrastructure now resolves these references from the \BeanFactory\, allowing for reusable, application-wide mapping logic instead of relying solely on default mapping behavior.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support · high confidence
Support for table names in SpEL expressions
Repository query strings can now reference table names using SpEL expressions (e.g., \#{tableName} or \#{qualifiedTableName}). This allows dynamic table resolution in derived and custom queries, with the preprocessor handling identifier quoting according to the configured database dialect.
spring-data-relational/src/main/java/org/springframework/data/relational/repository/support · high confidence
Architecture
Refactored core JDBC execution into dedicated executor and context classes
The core JDBC persistence logic has been restructured to improve maintainability and support new capabilities. A new \AggregateChangeExecutor\ class now handles the dispatching of database actions (inserts, updates, deletes, upserts, and pessimistic locking) to a dedicated \JdbcAggregateChangeExecutionContext\, which manages the execution state and results. This separation allows the \JdbcAggregateTemplate\ to focus on higher-level orchestration, event publishing, and callback handling. The refactoring also introduces new operations in \JdbcAggregateOperations\, such as \upsert\, \insert\, \update\, and \deleteByQuery\, and adds support for batch operations and optimistic locking version handling within the new execution context.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core · high confidence
Behavioural changes
Deprecate Kotlin extension methods returning Page
The Kotlin extension functions for \JdbcAggregateOperations\ that accept \Query\ or \Pageable\ and return a \Page\ are now deprecated. Users should instead use the generic \findAll\<T\>()\ and \count\<T\>()\ methods to construct \Page\ results manually, as the direct pagination extensions are no longer recommended in version 4.0.
spring-data-jdbc/src/main/kotlin · high confidence
Documentation examples now reference R2DBC source via symlink
The documentation examples for R2DBC are now provided as a symbolic link pointing to the actual test documentation sources in the spring-data-r2dbc module. This ensures that the examples included in the Antora documentation are kept in sync with the source code without requiring manual duplication.
src/main/antora/modules/ROOT/examples · high confidence
Migrate build to Spring Develocity Conventions and update JVM configuration
The Maven build now uses the Spring Develocity Conventions extension (version 0.0.26) to standardize build behavior and connect to ge.spring.io. Additionally, the JVM configuration has been updated to include specific exports and opens for JDK compiler modules and base packages, ensuring compatibility with the new build conventions.
.mvn · high confidence
New R2DBC query and update mapping infrastructure
The R2DBC module now includes a new query mapping package that introduces \QueryMapper\ and \UpdateMapper\ to handle the translation of Spring Data query abstractions (such as \CriteriaDefinition\, \Sort\, and \Update\) into SQL. This change adds support for mapping embedded properties in both queries and updates, allows arbitrary where clauses in single query loading, and enables the application of custom converters to collection-like values. It also introduces \SqlSort\ for validating sort expressions and ensures that converted identifiers are correctly considered in batch identifier queries.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/query · high confidence
New SQL DSL for building queries and conditions
The SQL generation layer has been replaced with a new, modular Domain Specific Language (DSL) located in the \core.sql\ package. This update introduces a comprehensive set of classes for constructing SQL statements programmatically, including \SelectBuilder\, \DefaultDeleteBuilder\, and \DefaultInsertBuilder\ for CRUD operations, alongside a rich expression tree with \Condition\, \Expression\, \Column\, and \Table\ types. The new API supports advanced SQL features such as windowing functions (\AnalyticFunction\), \CASE\ expressions, \CAST\, \BETWEEN\ conditions, and nested condition grouping via \nest()\. This change fundamentally alters how SQL is generated, moving from the previous implementation to this new visitor-based AST structure.
spring-data-relational/src/main/java/org/springframework/data/relational/core/sql · high confidence
New SQL rendering infrastructure for Spring Data JDBC
The \spring-data-relational\ module introduces a comprehensive visitor-based rendering engine for SQL generation. This new system replaces the previous implementation with a set of specialized visitors (e.g., \ConditionVisitor\, \ExpressionVisitor\, \SelectStatementVisitor\) that handle the translation of the SQL AST into SQL strings. This change enables support for advanced SQL features such as analytic functions, \CASE\ expressions, \CAST\, \BETWEEN\, \NOT IN\, and empty \IN\ lists, while also improving the handling of table aliases and column references.
spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render · high confidence
New core conversion and batching infrastructure for Spring Data JDBC
The \spring-data-relational/core/conversion\ package has been restructured with new foundational classes to improve how domain aggregates are mapped to and from the database. \AbstractRelationalConverter\ and \MappingRelationalConverter\ now serve as the central conversion engine, handling custom conversions, entity instantiation, and SpEL-based projections. To optimize database performance, \BatchedActions\ and \BatchingAggregateChange\ (including \DeleteBatchingAggregateChange\) group individual insert and delete operations into batched SQL commands, reducing round-trips. The new \DbAction\ interface and its implementations (e.g., \Insert\, \UpdateRoot\, \DeleteRoot\) provide a structured, immutable representation of database interactions, while \IdValueSource\ clarifies whether identifiers are provided or generated. These changes collectively enhance the reliability and efficiency of aggregate persistence.
spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion · high confidence
New mapping abstractions for aggregate references and JDBC-specific type handling
This release introduces new core mapping classes in the \org.springframework.data.jdbc.core.mapping\ package to improve how Spring Data JDBC handles aggregate relationships and database types. The new \AggregateReference\ interface and its \IdOnlyAggregateReference\ implementation allow entities to reference other aggregates by ID without requiring the full entity to be loaded, simplifying association management. Additionally, \BasicJdbcPersistentProperty\ extends the base relational property to recognize these references as associations, while \JdbcMappingContext\ and \JdbcSimpleTypes\ provide JDBC-specific metadata, including support for \JdbcValue\ which lets users explicitly control the \SQLType\ for bind parameters. These changes also align the mapping context with updated APIs in Spring Data Commons.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping · high confidence
R2DBC configuration and repository interfaces restructured
The Spring Data R2DBC configuration and repository packages have been reorganized to improve modularity and clarity. The core configuration logic is now centralized in a new \AbstractR2dbcConfiguration\ base class, which handles bean registration for essential components like \ConnectionFactory\, \R2dbcEntityTemplate\, and \R2dbcMappingContext\. Auditing support has been simplified through a dedicated \EnableR2dbcAuditing\ annotation and its associated registrar, making it easier to enable automatic timestamp and user tracking. Additionally, repository interfaces and annotations such as \R2dbcRepository\, \@Query\, and \@Modifying\ have been moved to a dedicated \repository\ package, providing a cleaner separation of concerns for developers defining reactive data access layers.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/config · high confidence
R2DBC conversion and mapping infrastructure refactored
The R2DBC conversion layer has been restructured to improve type safety and database integration. The core converter now reads from an intermediate RowDocument, providing a consistent abstraction for entity mapping. Support for database sequences has been added via the @Sequence annotation, allowing automatic identifier generation for entities. Enum handling is now more flexible, allowing users to retain actual enum values in the database through custom WritingConverters. Additionally, the conversion utilities have been updated to use JSpecify annotations for better nullability constraints.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/convert · high confidence
R2DBC core refactored to use Spring Framework's r2dbc support and JSpecify nullability
The R2DBC core module has been updated to align with Spring Framework's r2dbc changes. Deprecated internal classes for named parameter expansion (such as \NamedParameterExpander\ and \BindParameterSource\) have been removed in favor of Spring's native \org.springframework.r2dbc.core\ support. The codebase has also migrated to JSpecify annotations for nullability constraints, and the \R2dbcEntityTemplate\ now exposes a \StatementFilterFunction\ to allow users to apply custom filters to every reactive statement.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core · high confidence
R2DBC mapping layer refactored with new identifier quoting defaults and type handling
The R2DBC mapping package has been restructured to introduce \OutboundRow\ for representing data to be written, \ParameterAdapter\ to bridge Spring's \Parameter\ with the R2DBC SPI, and \R2dbcSimpleTypeHolder\ to recognize R2DBC-specific types like \Blob\, \Clob\, and \Parameter\ as simple types. Additionally, \R2dbcMappingContext\ now defaults to quoted identifiers (case-sensitive) while providing explicit factory methods for plain identifiers, and the package has migrated to JSpecify annotations for nullability constraints.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/mapping · high confidence
R2DBC repository query execution is rewritten to support SpEL expressions and reactive parameter resolution
The R2DBC repository query layer has been refactored to support Spring Expression Language (SpEL) in string-based queries (using :\#{…} syntax) and to resolve reactive wrapper types (Mono/Flux) in method parameters. This change introduces a new query execution model where parameter binding and result processing are handled by dedicated classes (ExpressionEvaluatingParameterBinder, R2dbcQueryExecution), enabling dynamic value evaluation and proper handling of reactive return types. It also enforces that string-based queries cannot use Slice, Page, or Limit parameters, and adds support for pessimistic locking in derived queries.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/repository/query · high confidence
R2DBC repository support infrastructure restructured and enhanced
The R2DBC repository support layer has been restructured to introduce new factory classes (R2dbcRepositoryFactory, R2dbcRepositoryFactoryBean) for creating repository instances, and added support for reactive fluent queries with limit and scroll capabilities via ReactiveFluentQuerySupport and ScrollDelegate. The implementation now relies on QueryMapper for mapping embeddable identifiers in by-id queries, aligns OffsetScrolling to zero-based indexes, and adopts JSpecify annotations for nullability constraints.
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/repository/support · high confidence
Redesigned lifecycle events and callbacks for Spring Data JDBC
The lifecycle event system in Spring Data Relational has been redesigned to improve type safety and usability. Events now use generics to match specific ApplicationEvent subtypes with their generic payload parameters, allowing listeners to handle events more precisely. A new base listener, AbstractRelationalEventListener, automatically resolves the domain class type argument to filter events correctly. Additionally, the event model now includes an Identifier wrapper for entity IDs and exposes AggregateChange information in save and delete events, giving callbacks access to the planned database actions. Callbacks like BeforeConvertCallback and AfterConvertCallback are now integrated into this unified event framework, enabling developers to intercept and modify entities at specific points in the persistence lifecycle with stronger type guarantees.
spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event · high confidence
Refactored JDBC conversion and data access strategy internals
The \spring-data-jdbc\ core conversion package has been significantly restructured to improve modularity and performance. Key changes include the introduction of \AggregateReader\ to handle aggregate loading via \SingleQuerySqlGenerator\ and \RowDocument\, and the addition of \Association\ to better detect and handle complex identifier types in associations. The data access layer now utilizes a \DataAccessStrategyFactory\ to configure \SingleQueryFallbackDataAccessStrategy\ or \DefaultDataAccessStrategy\ based on mapping context settings, while \CascadingDataAccessStrategy\ and \DelegatingDataAccessStrategy\ manage strategy delegation. Utility classes like \ArrayUtils\ and \BindParameterNameSanitizer\ have been added to support array conversions and SQL identifier sanitization, and \DefaultJdbcTypeFactory\ now uses \SQLType\ for more accurate JDBC type handling.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert · high confidence
Refactored SQL dialect rendering and introduced upsert support
The dialect system in spring-data-relational has been restructured to use a composable rendering context (SelectRenderContext) that delegates SQL clause generation (such as LIMIT/OFFSET and locking) to specific dialect implementations like AnsiDialect, Db2Dialect, and H2Dialect. This change also introduces a new UpsertRenderContext, enabling single-statement upsert operations via MERGE or INSERT … ON CONFLICT syntax, and adds support for dialect-specific identifier processing and array column handling.
spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect · high confidence
Refactored repository query execution and parameter binding infrastructure
The query execution and parameter handling logic in the repository query package has been restructured to improve modularity and type safety. A new delegation pattern for row mapping is introduced via AbstractDelegatingRowMapper and ConvertingRowMapper, allowing post-processing of mapped results. Query execution strategies are now encapsulated in JdbcQueryExecution, while JdbcQueryCreator and its specialized variants (JdbcCountQueryCreator, JdbcDeleteQueryCreator) handle the generation of SQL statements from derived query methods. Parameter binding is standardized through JdbcParameters and ParameterBinding, which leverage java.sql.SQLType for accurate type resolution, and EscapingParameterSource ensures proper value escaping. These changes collectively provide a more robust and extensible foundation for repository query methods.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query · high confidence
Restructured Spring Data JDBC configuration infrastructure
The repository configuration package has been refactored to improve modularity and support Ahead-of-Time (AOT) compilation. \AbstractJdbcConfiguration\ now serves as the central base class for bean registration, while \JdbcConfiguration\ provides static factory methods for core components like the converter and mapping context. The \@EnableJdbcRepositories\ annotation now prioritizes \jdbcAggregateOperationsRef\ for consistent configuration, deprecating the older \jdbcOperationsRef\ and \dataAccessStrategyRef\ attributes. Additionally, strict repository scanning is enforced by requiring the \@Table\ annotation, and AOT support is enabled via \JdbcRepositoryRegistrationAotProcessor\.
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config · high confidence
Test coverage
Added AOT integration test schema for JDBC repository contributor; Added ArchUnit tests to enforce package dependency rules; Added ArchUnit-based dependency cycle tests and event capturing utility; Added ArchUnit-based dependency cycle tests for Spring Data R2DBC; Added CI Docker image proxy substitutor for Testcontainers; Added JMH benchmarks for mapping and SQL generation; Added Kotlin unit tests for Criteria API extensions; Added MyBatis integration tests for optimistic locking and context handling; Added SQL schema files for H2 and Postgres dialect integration tests; Added SQL schema files for integration tests; Added SQL schema scripts for JDBC repository integration tests; Added database schema scripts for integration tests; Added documentation tests for R2DBC repository and template usage; Added integration and unit tests for R2DBC repository support; Added test configuration files for logging and MySQL; Added test infrastructure for JDBC named queries and testing utilities; Added test resources for MyBatis integration tests; Added test resources for foreign key schema generation; Added tests for Ahead-of-Time (AOT) repository support; Added tests for Liquibase schema generation and diffing; Added tests for R2DBC core functionality; Added tests for R2DBC repository configuration and registration; Added unit and integration tests for JDBC dialect conversions; Added unit and integration tests for R2DBC configuration and auditing; Added unit and integration tests for Spring Data JDBC query execution; Added unit tests for Criteria, Query, and Update classes; Added unit tests for DefaultNamingStrategy; Added unit tests for JDBC repository support classes; Added unit tests for JdbcUtil SQL type mapping; Added unit tests for Kotlin coroutine extensions and repositories; Added unit tests for Kotlin extension functions on JdbcAggregateOperations; Added unit tests for R2DBC conversion and mapping components; Added unit tests for R2DBC dialect resolution and specific database dialects; Added unit tests for R2DBC query and update mapping logic; Added unit tests for SQL generation aliasing and query patterns; Added unit tests for SQL rendering components; Added unit tests for SqlSort validation and construction; Added unit tests for TableNameQueryPreprocessor; Added unit tests for core conversion and data access components; Added unit tests for dialect-specific SQL rendering and utility behavior; Added unit tests for mapping core components; Added unit tests for mapping metadata and reference equality; Added unit tests for relational conversion and batching logic; Added unit tests for relational event listeners and generic type handling; Added unit tests for the SQL Statement Builder API; Added unit tests for upsert SQL rendering; Expanded integration test coverage for R2DBC repositories; Expanded test coverage for Spring Data JDBC core operations; Expanded test coverage for Spring Data JDBC repository behaviors; Expanded test coverage for Spring Data JDBC repository configuration; New R2DBC integration test infrastructure; New test infrastructure for database-specific integration testing.
Dependencies
Spring Data Relational 4.2.0-SNAPSHOT dependency baseline
The project dependency manifests have been updated to the 4.2.0-SNAPSHOT release train. This establishes the baseline versions for core libraries including Spring Data Commons 4.2.0-SNAPSHOT, MyBatis 3.5.13, and Liquibase 4.21.1. Database driver dependencies are set to PostgreSQL 42.7.13, MySQL Connector/J 26.7.0, MariaDB 3.5.10, MS SQL Server 13.6.0.jre11, DB2 12.1.5.0, Oracle 23.26.3.0.0, H2 2.5.250, and HSQLDB 2.7.3. R2DBC drivers are aligned with PostgreSQL 1.1.2.RELEASE, MySQL 1.4.3, MariaDB 1.3.0, MS SQL Server 1.0.6.RELEASE, and Oracle 1.3.0. Test dependencies include ArchUnit 1.4.1 and Netty 4.2.13.Final.
(dependencies) · high confidence
Upgrade Maven Wrapper to version 3.9.16
The Maven Wrapper configuration has been updated to use Maven distribution version 3.9.16. This ensures that builds executed via the wrapper will consistently use this specific Maven release, aligning the local development and CI environments with the latest wrapper standards.
.mvn/wrapper · high confidence
Housekeeping
Accept third-party Docker image licenses for CI
A new script has been added to automatically accept the third-party licenses for the Docker images used in integration tests, specifically Microsoft SQL Server (versions 2022 and 2025) and IBM DB2 (version 11.5.7.0a). This ensures that the test containers can run without manual license acceptance in the CI environment.
ci · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 66 → 57 (-8.5)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 84 → 90 (+5.9)
- Architecture 99 → 65 (-33.9)
- Maturity 55 → 51 (-3.7)
- Readiness 69 → 72 (+3.8)
- Security 73 → 51 (-21.2)
- Domain Modelling 100 → 100 (+0.0)
Resolved (46)
- Change coupling clique: CascadingDataAccessStrategy.java, DefaultDataAccessStrategy.java, DelegatingDataAccessStrategy.java (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java)
- Change coupling: EntityRowMapper.java ↔ MapEntityRowMapper.java (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/EntityRowMapper.java)
- Change coupling: IdGeneratingBatchInsertStrategy.java ↔ IdGeneratingInsertStrategy.java (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/IdGeneratingBatchInsertStrategy.java)
- Coverage not included — suite not readable by the collector
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- Duplicated block (10 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategyFactory.java)
- Duplicated block (10 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- Duplicated block (10 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- Duplicated block (10 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryCreator.java)
- Duplicated block (10 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java)
- Duplicated block (11 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- Duplicated block (11 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- Duplicated block (11 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- Duplicated block (11 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java)
- Duplicated block (12 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java)
- Duplicated block (12 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- Duplicated block (12 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/aot/AotRepositoryFragmentSupport.java)
- Duplicated block (13 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java)
- Duplicated block (13 lines × 2) (spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/FilteredSingleConditionRenderSupport.java)
- Duplicated block (14 lines × 2) (spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/OracleDialect.java)
- …and 26 more
New (288)
- AggregateChangeExecutor.execute (cognitive 18) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java)
- AggregateChangeExecutor.execute (cyclomatic 18) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java)
- Boundary-crossing change coupling: SqlGenerator.java ↔ RelationalEntityDeleteWriter.java (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java)
- Change coupling: DefaultDataAccessStrategy.java ↔ DelegatingDataAccessStrategy.java (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java)
- Change coupling: DelegatingDataAccessStrategy.java ↔ SqlGenerator.java (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DelegatingDataAccessStrategy.java)
- Change coupling: SqlGenerator.java ↔ SqlIdentifierParameterSource.java (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java)
- Change-coupling hub: CascadingDataAccessStrategy.java → JdbcAggregateTemplate.java, DefaultDataAccessStrategy.java, DelegatingDataAccessStrategy.java, SqlGenerator.java (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/CascadingDataAccessStrategy.java)
- ClassTooLong: JdbcCodeBlocks (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/aot/JdbcCodeBlocks.java)
- ClassTooLong: MappingRelationalConverter (spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java)
- ClassTooLong: QueryMapper (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- ClassTooLong: QueryMapper (spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java)
- ClassTooLong: R2dbcEntityTemplate (spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplate.java)
- ClassTooLong: SqlGenerator (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java)
- Dependency hygiene PARTLY measured — Maven/Gradle declarations read, no dependency graph resolved
- Duplicated block (10 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcCustomConversions.java)
- Duplicated block (10 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- Duplicated block (10 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java)
- Duplicated block (10 lines × 2) (spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/BetweenVisitor.java)
- Duplicated block (102 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/dialect/DialectResolver.java)
- Duplicated block (11 lines × 2) (spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java)
- …and 268 more
Changes since last survey
- 36 commits — 34 feature/other, 2 fixes
By area
- (root) — 14 commits
- spring-data-jdbc/src — 11 commits
- spring-data-r2dbc/src — 3 commits
- (repo) — 2 commits
- .github/actions — 2 commits
- spring-data-relational/src — 2 commits
- .mvn/extensions.xml — 1 commit
- src/main — 1 commit
Notable commits
- fix: Fix @InsertOnlyProperty handling for embedded properties
- fix: Fix AOT-generated GreaterThanEqual derived query.
- change: Add release train automation.
- change: Add support for unicode column names.
- change: Consider custom write converters first
- change: Create foreign keys for references between aggregates
- change: Disable JdbcAggregateTemplateSchemaIntegrationTests for Oracle.
- change: Emit Sort.Order separator before non-first orders in AOT generation
- change: Enable SQL server integration tests on Apple Silicon (aarch64).
- change: Ensure stable test results.
- change: Enter rampdown phase for 4.2.0-M1.
- change: Enter rampdown phase for 4.2.0-M2.
- change: Extend the consideration of insert only to AggregateReferences
- change: Fix typos
- change: Polishing
- change: Polishing
- change: Polishing.
- change: Polishing.
- change: Prepare next development iteration.
- change: Release version 4.2.0-M1 (2026.1.0).
- …and 16 more
Architecture
- Containers 0 added · 0 removed · contexts 2 added · 0 removed · edges 2 added · 0 removed
Added bounded contexts (2)
- spring-data-jdbc
- spring-data-r2dbc
Added dependency edges (2)
- spring-data-jdbc → spring-data-relational
- spring-data-r2dbc → spring-data-relational
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
spring-projects/spring-data-relational was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 22 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 4688a8b1cf2f8338e8b9f2d58e9cb281210ad5b6 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-90d5d2fe38ee.