main 5c38162264cb cached
158 files
462.9 KB
114.7k tokens
1105 symbols
1 requests
Download .txt
Showing preview only (516K chars total). Download the full file or copy to clipboard to get everything.
Repository: spring-projects/spring-data-keyvalue
Branch: main
Commit: 5c38162264cb
Files: 158
Total size: 462.9 KB

Directory structure:
gitextract_fy98wr_9/

├── .github/
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── README.template.adoc
│   ├── dco.yml
│   └── workflows/
│       ├── ci.yml
│       ├── codeql.yml
│       ├── project.yml
│       └── snapshots.yml
├── .gitignore
├── .mvn/
│   ├── extensions.xml
│   ├── jvm.config
│   └── wrapper/
│       ├── maven-wrapper.jar
│       └── maven-wrapper.properties
├── CI.adoc
├── CONTRIBUTING.adoc
├── LICENSE.txt
├── README.adoc
├── SECURITY.adoc
├── mvnw
├── mvnw.cmd
├── package.json
├── pom.xml
├── settings.xml
└── src/
    ├── main/
    │   ├── antora/
    │   │   ├── antora-playbook.yml
    │   │   ├── antora.yml
    │   │   ├── modules/
    │   │   │   └── ROOT/
    │   │   │       ├── nav.adoc
    │   │   │       └── pages/
    │   │   │           ├── commons/
    │   │   │           │   └── upgrade.adoc
    │   │   │           ├── index.adoc
    │   │   │           ├── keyvalue/
    │   │   │           │   ├── repository/
    │   │   │           │   │   └── map-repositories.adoc
    │   │   │           │   ├── template.adoc
    │   │   │           │   └── value-expressions.adoc
    │   │   │           ├── keyvalue.adoc
    │   │   │           ├── repositories/
    │   │   │           │   ├── core-concepts.adoc
    │   │   │           │   ├── core-domain-events.adoc
    │   │   │           │   ├── core-extensions.adoc
    │   │   │           │   ├── create-instances.adoc
    │   │   │           │   ├── custom-implementations.adoc
    │   │   │           │   ├── definition.adoc
    │   │   │           │   ├── null-handling.adoc
    │   │   │           │   ├── object-mapping.adoc
    │   │   │           │   ├── projections.adoc
    │   │   │           │   ├── query-keywords-reference.adoc
    │   │   │           │   ├── query-methods-details.adoc
    │   │   │           │   └── query-return-types-reference.adoc
    │   │   │           └── repositories.adoc
    │   │   └── resources/
    │   │       └── antora-resources/
    │   │           └── antora.yml
    │   ├── java/
    │   │   └── org/
    │   │       └── springframework/
    │   │           └── data/
    │   │               ├── keyvalue/
    │   │               │   ├── annotation/
    │   │               │   │   ├── KeySpace.java
    │   │               │   │   └── package-info.java
    │   │               │   ├── aot/
    │   │               │   │   ├── KeyValueRuntimeHints.java
    │   │               │   │   └── package-info.java
    │   │               │   ├── core/
    │   │               │   │   ├── AbstractKeyValueAdapter.java
    │   │               │   │   ├── CriteriaAccessor.java
    │   │               │   │   ├── DefaultIdentifierGenerator.java
    │   │               │   │   ├── ForwardingCloseableIterator.java
    │   │               │   │   ├── GeneratingIdAccessor.java
    │   │               │   │   ├── IdentifierGenerator.java
    │   │               │   │   ├── IterableConverter.java
    │   │               │   │   ├── KeyValueAdapter.java
    │   │               │   │   ├── KeyValueCallback.java
    │   │               │   │   ├── KeyValueOperations.java
    │   │               │   │   ├── KeyValuePersistenceExceptionTranslator.java
    │   │               │   │   ├── KeyValueTemplate.java
    │   │               │   │   ├── PathSortAccessor.java
    │   │               │   │   ├── PredicateQueryEngine.java
    │   │               │   │   ├── PropertyPathComparator.java
    │   │               │   │   ├── QueryEngine.java
    │   │               │   │   ├── QueryEngineFactory.java
    │   │               │   │   ├── SimplePropertyPathAccessor.java
    │   │               │   │   ├── SortAccessor.java
    │   │               │   │   ├── SpelCriteria.java
    │   │               │   │   ├── SpelCriteriaAccessor.java
    │   │               │   │   ├── SpelPropertyComparator.java
    │   │               │   │   ├── SpelQueryEngine.java
    │   │               │   │   ├── SpelSortAccessor.java
    │   │               │   │   ├── UncategorizedKeyValueException.java
    │   │               │   │   ├── event/
    │   │               │   │   │   ├── KeyValueEvent.java
    │   │               │   │   │   └── package-info.java
    │   │               │   │   ├── mapping/
    │   │               │   │   │   ├── AnnotationBasedKeySpaceResolver.java
    │   │               │   │   │   ├── BasicKeyValuePersistentEntity.java
    │   │               │   │   │   ├── ClassNameKeySpaceResolver.java
    │   │               │   │   │   ├── KeySpaceResolver.java
    │   │               │   │   │   ├── KeyValuePersistentEntity.java
    │   │               │   │   │   ├── KeyValuePersistentProperty.java
    │   │               │   │   │   ├── PrefixKeyspaceResolver.java
    │   │               │   │   │   ├── context/
    │   │               │   │   │   │   ├── KeyValueMappingContext.java
    │   │               │   │   │   │   └── package-info.java
    │   │               │   │   │   └── package-info.java
    │   │               │   │   ├── package-info.java
    │   │               │   │   └── query/
    │   │               │   │       ├── KeyValueQuery.java
    │   │               │   │       └── package-info.java
    │   │               │   └── repository/
    │   │               │       ├── KeyValueRepository.java
    │   │               │       ├── config/
    │   │               │       │   ├── KeyValueRepositoryConfigurationExtension.java
    │   │               │       │   ├── QueryCreatorType.java
    │   │               │       │   └── package-info.java
    │   │               │       ├── package-info.java
    │   │               │       ├── query/
    │   │               │       │   ├── CachingKeyValuePartTreeQuery.java
    │   │               │       │   ├── KeyValuePartTreeQuery.java
    │   │               │       │   ├── PredicateQueryCreator.java
    │   │               │       │   ├── SpelQueryCreator.java
    │   │               │       │   └── package-info.java
    │   │               │       └── support/
    │   │               │           ├── KeyValueQuerydslUtils.java
    │   │               │           ├── KeyValueRepositoryFactory.java
    │   │               │           ├── KeyValueRepositoryFactoryBean.java
    │   │               │           ├── QuerydslKeyValuePredicateExecutor.java
    │   │               │           ├── QuerydslKeyValueRepository.java
    │   │               │           ├── SimpleKeyValueRepository.java
    │   │               │           └── package-info.java
    │   │               └── map/
    │   │                   ├── KeySpaceStore.java
    │   │                   ├── MapKeySpaceStore.java
    │   │                   ├── MapKeyValueAdapter.java
    │   │                   ├── package-info.java
    │   │                   └── repository/
    │   │                       └── config/
    │   │                           ├── EnableMapRepositories.java
    │   │                           ├── MapRepositoriesRegistrar.java
    │   │                           ├── MapRepositoryConfigurationExtension.java
    │   │                           └── package-info.java
    │   └── resources/
    │       ├── META-INF/
    │       │   ├── spring/
    │       │   │   └── aot.factories
    │       │   └── spring.factories
    │       ├── license.txt
    │       └── notice.txt
    └── test/
        ├── java/
        │   └── org/
        │       └── springframework/
        │           └── data/
        │               ├── keyvalue/
        │               │   ├── CustomKeySpaceAnnotationWithAliasFor.java
        │               │   ├── Person.java
        │               │   ├── SubclassOfTypeWithCustomComposedKeySpaceAnnotation.java
        │               │   ├── TypeWithCustomComposedKeySpaceAnnotationUsingAliasFor.java
        │               │   ├── TypeWithDirectKeySpaceAnnotation.java
        │               │   ├── TypeWithInhteritedPersistentAnnotationNotHavingKeySpace.java
        │               │   ├── TypeWithPersistentAnnotationNotHavingKeySpace.java
        │               │   ├── core/
        │               │   │   ├── DefaultIdentifierGeneratorUnitTests.java
        │               │   │   ├── ForwardingCloseableIteratorUnitTests.java
        │               │   │   ├── IterableConverterUnitTests.java
        │               │   │   ├── KeyValuePersistenceExceptionTranslatorUnitTests.java
        │               │   │   ├── KeyValueTemplateTests.java
        │               │   │   ├── KeyValueTemplateUnitTests.java
        │               │   │   ├── PredicateQueryEngineUnitTests.java
        │               │   │   ├── PropertyPathComparatorUnitTests.java
        │               │   │   ├── SpelPropertyComparatorUnitTests.java
        │               │   │   ├── SpelQueryEngineUnitTests.java
        │               │   │   └── mapping/
        │               │   │       ├── AnnotationBasedKeySpaceResolverUnitTests.java
        │               │   │       ├── BasicKeyValuePersistentEntityUnitTests.java
        │               │   │       ├── PrefixKeyspaceResolverUnitTests.java
        │               │   │       └── context/
        │               │   │           └── KeyValueMappingContextUnitTests.java
        │               │   └── repository/
        │               │       ├── MapRepositoriesRegistrarUnitTests.java
        │               │       ├── SimpleKeyValueRepositoryUnitTests.java
        │               │       ├── query/
        │               │       │   ├── AbstractQueryCreatorTestBase.java
        │               │       │   ├── CachingKeyValuePartTreeQueryUnitTests.java
        │               │       │   ├── KeyValuePartTreeQueryUnitTests.java
        │               │       │   ├── PredicateQueryCreatorUnitTests.java
        │               │       │   └── SpelQueryCreatorUnitTests.java
        │               │       └── support/
        │               │           ├── KeyValueQuerydslUtilsUnitTests.java
        │               │           └── KeyValueRepositoryFactoryBeanUnitTests.java
        │               └── map/
        │                   ├── AbstractRepositoryUnitTests.java
        │                   ├── CachingQuerySimpleKeyValueRepositoryUnitTests.java
        │                   ├── MapDbIntegrationTests.java
        │                   ├── MapKeyValueAdapterUnitTests.java
        │                   ├── QuerydslKeyValuePredicateExecutorUnitTests.java
        │                   ├── SimpleKeyValueRepositoryUnitTests.java
        │                   └── repository/
        │                       └── config/
        │                           ├── MapRepositoriesConfigurationExtensionIntegrationTests.java
        │                           ├── MapRepositoryRegistrarWithFullDefaultingIntegrationTests.java
        │                           └── MapRepositoryRegistrarWithTemplateDefinitionIntegrationTests.java
        └── resources/
            └── logback.xml

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--

Thank you for proposing a pull request. This template will guide you through the essential steps necessary for a pull request.
Make sure that:

-->

- [ ] You have read the [Spring Data contribution guidelines](https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc).
- [ ] You use the code formatters provided [here](https://github.com/spring-projects/spring-data-build/tree/master/etc/ide) and have them applied to your changes. Don’t submit any formatting related changes.
- [ ] You submit test cases (unit or integration tests) that back your changes.
- [ ] You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).


================================================
FILE: .github/README.template.adoc
================================================
= Spring Data KeyValue image:https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Develocity", link="https://ge.spring.io/scans?search.rootProjectNames=Spring Data KeyValue"]

The primary goal of the https://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.

This module provides infrastructure components to build repository abstractions for stores dealing with Key/Value pairs and ships with a default `java.util.Map` based implementation.

== Features

* Infrastructure for building repositories on top of key/value implementations.
* Dynamic SpEL query generation from query method names.
* Possibility to integrate custom repository code.

== Code of Conduct

This project is governed by the https://github.com/spring-projects/.github/blob/main/CODE_OF_CONDUCT.md[Spring Code of Conduct].
By participating, you are expected to uphold this code of conduct.
Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.

== Getting Started

Here is a quick teaser of an application using Spring Data Repositories in Java:

[source,java]
----
public interface PersonRepository extends CrudRepository<Person, Long> {

    List<Person> findByLastname(String lastname);

    List<Person> findByFirstnameLike(String firstname);
}

@Service
public class MyService {

    private final PersonRepository repository;

    public MyService(PersonRepository repository) {
        this.repository = repository;
    }

    public void doWork() {

        repository.deleteAll();

        Person person = new Person();
        person.setFirstname("Oliver");
        person.setLastname("Gierke");
        repository.save(person);

        List<Person> lastNameResults = repository.findByLastname("Gierke");
        List<Person> firstNameResults = repository.findByFirstnameLike("Oli*");
    }
}

@KeySpace("person")
class Person {

    @Id String uuid;
    String firstname;
    String lastname;

    // getters and setters omitted for brevity
}

@Configuration
@EnableMapRepositories("com.acme.repositories")
class AppConfig { … }
----

=== Maven configuration

Add the Maven dependency:

[source,xml]
----
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-keyvalue</artifactId>
    <version>${version}.RELEASE</version>
</dependency>
----

If you'd rather like the latest snapshots of the upcoming major version, use our Maven snapshot repository and declare the appropriate dependency version.

[source,xml]
----
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-keyvalue</artifactId>
    <version>${version}-SNAPSHOT</version>
</dependency>

<repository>
    <id>spring-snapshot</id>
    <name>Spring Snapshot Repository</name>
    <url>https://repo.spring.io/snapshot</url>
</repository>
----

== Getting Help

Having trouble with Spring Data?
We’d love to help!

* Check the
https://docs.spring.io/spring-data/keyvalue/reference/[reference documentation], and https://docs.spring.io/spring-data/keyvalue/docs/current/api/[Javadocs].
* Learn the Spring basics – Spring Data builds on Spring Framework, check the https://spring.io[spring.io] web-site for a wealth of reference documentation.
If you are just starting out with Spring, try one of the https://spring.io/guides[guides].
* If you are upgrading, check out the https://github.com/spring-projects/spring-data-commons/wiki#release-notes[release notes] for "`new and noteworthy`" features.
* Ask a question - we monitor https://stackoverflow.com[stackoverflow.com] for questions tagged with https://stackoverflow.com/tags/spring-data[`spring-data-keyvalue`].
* Report bugs with Spring Data KeyValue via https://github.com/spring-projects/spring-data-keyvalue/issues[Github].

== Reporting Issues

Spring Data uses Github as issue tracking system to record bugs and feature requests.
If you want to raise an issue, please follow the recommendations below:

* Before you log a bug, please search the https://github.com/spring-projects/spring-data-keyvalue/issues[issue tracker] to see if someone has already reported the problem.
* If the issue does not already exist, https://github.com/spring-projects/spring-data-keyvalue/issues/new[create a new issue].
* Please provide as much information as possible with the issue report, we like to know the version of Spring Data that you are using, the JVM version, Stacktrace, etc.
* If you need to paste code, or include a stack trace use https://guides.github.com/features/mastering-markdown/[Markdown] code fences +++```+++.
* If possible try to create a test-case or project that replicates the issue.
Attach a link to your code or a compressed file containing your code.

== Building from Source

You don’t need to build from source to use Spring Data (binaries in https://repo.spring.io[repo.spring.io]), but if you want to try out the latest and greatest, Spring Data can be easily built with the https://github.com/takari/maven-wrapper[maven wrapper].
You also need JDK 17.

[source,bash]
----
 $ ./mvnw clean install
----

If you want to build with the regular `mvn` command, you will need https://maven.apache.org/run-maven/index.html[Maven v3.5.0 or above].

_Also see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] if you wish to submit pull requests, and in particular please sign the https://cla.pivotal.io/sign/spring[Contributor’s Agreement] before your first change, is trivial._

=== Building reference documentation

Building the documentation builds also the project without running tests.

[source,bash]
----
 $ ./mvnw clean install -Pantora
----

The generated documentation is available from `target/antora/site/index.html`.

== Examples

* https://github.com/spring-projects/spring-data-examples/[Spring Data Examples] contains example projects that explain specific features in more detail.

== License

Spring Data KeyValue is Open Source software released under the https://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license].


================================================
FILE: .github/dco.yml
================================================
require:
  members: false


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI Build

on:
  workflow_dispatch:
  push:
    branches: [ main, 'issue/**' ]

permissions: read-all

jobs:
  build-java:
    strategy:
      matrix:
        java-version: [ base, main ]
    name: Build project
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Setup Java and Maven
        uses: spring-projects/spring-data-build/actions/setup-maven@main
        with:
          java-version: ${{ matrix.java-version }}
          develocity-access-key: '${{ secrets.DEVELOCITY_ACCESS_KEY }}'
      - name: Build
        uses: spring-projects/spring-data-build/actions/maven-build@main


================================================
FILE: .github/workflows/codeql.yml
================================================
# GitHub Actions for CodeQL Scanning

name: "CodeQL Advanced"

on:
  push:
  pull_request:
  workflow_dispatch:
  schedule:
    # https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule
    - cron: '0 5 * * *'

permissions: read-all

jobs:
  codeql-analysis-call:
    permissions:
      actions: read
      contents: read
      security-events: write
    uses: spring-io/github-actions/.github/workflows/codeql-analysis.yml@1


================================================
FILE: .github/workflows/project.yml
================================================
# GitHub Actions to automate GitHub issues for Spring Data Project Management

name: Spring Data GitHub Issues

on:
  issues:
    types: [opened, edited, reopened]
  issue_comment:
    types: [created]
  pull_request_target:
    types: [opened, edited, reopened]

permissions:
  contents: read
  issues: write
  pull-requests: write

jobs:
  Inbox:
    runs-on: ubuntu-latest
    if: github.repository_owner == 'spring-projects' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request == null && !contains(join(github.event.issue.labels.*.name, ', '), 'dependency-upgrade') && !contains(github.event.issue.title, 'Release ')
    steps:
      - name: Create or Update Issue Card
        uses: actions/add-to-project@v1.0.2
        with:
          project-url: https://github.com/orgs/spring-projects/projects/25
          github-token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}
  Pull-Request:
    runs-on: ubuntu-latest
    if: github.repository_owner == 'spring-projects' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request != null
    steps:
      - name: Create or Update Pull Request Card
        uses: actions/add-to-project@v1.0.2
        with:
          project-url: https://github.com/orgs/spring-projects/projects/25
          github-token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}
  Feedback-Provided:
    runs-on: ubuntu-latest
    if: github.repository_owner == 'spring-projects' && github.event_name == 'issue_comment' && github.event.action == 'created' && github.actor != 'spring-projects-issues' && github.event.pull_request == null && github.event.issue.state == 'open' && contains(toJSON(github.event.issue.labels), 'waiting-for-feedback')
    steps:
      - name: Update Project Card
        uses: actions/add-to-project@v1.0.2
        with:
          project-url: https://github.com/orgs/spring-projects/projects/25
          github-token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}


================================================
FILE: .github/workflows/snapshots.yml
================================================
name: Snapshots

on:
  workflow_dispatch:
  push:
    branches: [ main, 'issue/**' ]

permissions: read-all

jobs:
  build-snapshots:
    name: Build and deploy snapshots
    if: ${{ github.repository_owner == 'spring-projects' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Setup Java and Maven
        uses: spring-projects/spring-data-build/actions/setup-maven@main
        with:
          develocity-access-key: '${{ secrets.DEVELOCITY_ACCESS_KEY }}'
      - name: Deploy to Artifactory
        uses: spring-projects/spring-data-build/actions/maven-artifactory-deploy@main
        with:
          build-name: 'spring-data-keyvalue'
          username: '${{ secrets.ARTIFACTORY_USERNAME }}'
          password: '${{ secrets.ARTIFACTORY_PASSWORD }}'


================================================
FILE: .gitignore
================================================
target/
.settings/
.project
.classpath
.springBeans
.DS_Store
*.iml
*.ipr
*.iws
/.idea/
node_modules
node
package-lock.json
build/
.mvn/.develocity


================================================
FILE: .mvn/extensions.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<extensions>
	<extension>
		<groupId>io.spring.develocity.conventions</groupId>
		<artifactId>develocity-conventions-maven-extension</artifactId>
		<version>0.0.25</version>
	</extension>
</extensions>


================================================
FILE: .mvn/jvm.config
================================================
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
--add-opens=java.base/java.text=ALL-UNNAMED
--add-opens=java.desktop/java.awt.font=ALL-UNNAMED


================================================
FILE: .mvn/wrapper/maven-wrapper.properties
================================================
#Thu Jul 17 13:59:50 CEST 2025
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip


================================================
FILE: CI.adoc
================================================
= Continuous Integration

== Running CI tasks locally

You can run CI jobs locally using Docker and act[https://nektosact.com/].


================================================
FILE: CONTRIBUTING.adoc
================================================
= Spring Data contribution guidelines

You find the contribution guidelines for Spring Data projects https://github.com/spring-projects/spring-data-build/blob/main/CONTRIBUTING.adoc[here].


================================================
FILE: LICENSE.txt
================================================

                                 Apache License
                           Version 2.0, January 2004
                        https://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       https://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.adoc
================================================
= Spring Data KeyValue image:https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Develocity", link="https://ge.spring.io/scans?search.rootProjectNames=Spring Data KeyValue"]

The primary goal of the https://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.

This module provides infrastructure components to build repository abstractions for stores dealing with Key/Value pairs and ships with a default `java.util.Map` based implementation.

== Features

* Infrastructure for building repositories on top of key/value implementations.
* Dynamic SpEL query generation from query method names.
* Possibility to integrate custom repository code.

include::https://raw.githubusercontent.com/spring-projects/spring-data-build/refs/heads/main/etc/readme/code-of-conduct.adoc[]

== Getting Started

Here is a quick teaser of an application using Spring Data Repositories in Java:

[source,java]
----
public interface PersonRepository extends CrudRepository<Person, Long> {

    List<Person> findByLastname(String lastname);

    List<Person> findByFirstnameLike(String firstname);
}

@Service
public class MyService {

    private final PersonRepository repository;

    public MyService(PersonRepository repository) {
        this.repository = repository;
    }

    public void doWork() {

        repository.deleteAll();

        Person person = new Person();
        person.setFirstname("Oliver");
        person.setLastname("Gierke");
        repository.save(person);

        List<Person> lastNameResults = repository.findByLastname("Gierke");
        List<Person> firstNameResults = repository.findByFirstnameLike("Oli*");
    }
}

@KeySpace("person")
class Person {

    @Id String uuid;
    String firstname;
    String lastname;

    // getters and setters omitted for brevity
}

@Configuration
@EnableMapRepositories("com.acme.repositories")
class AppConfig { … }
----

include::https://raw.githubusercontent.com/spring-projects/spring-data-build/refs/heads/main/etc/readme/dependencies.adoc[]

include::https://raw.githubusercontent.com/spring-projects/spring-data-build/refs/heads/main/etc/readme/getting-help.adoc[]

include::https://raw.githubusercontent.com/spring-projects/spring-data-build/refs/heads/main/etc/readme/license.adoc[]


================================================
FILE: SECURITY.adoc
================================================
= Security Policy

== Reporting a Vulnerability

Please, https://github.com/spring-projects/security-advisories/security/advisories/new[open a draft security advisory] if you need to disclose and discuss a security issue in private with the Spring Data team.
Note that we only accept reports against https://spring.io/projects/spring-data#support[supported versions].

For more details, check out our https://spring.io/security-policy[security policy].

== JAR signing

Spring Data JARs released on Maven Central are signed.
You'll find more information about the key here: https://spring.io/GPG-KEY-spring.txt

Versions released prior to 2023 may be signed with a different key.


================================================
FILE: mvnw
================================================
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------

# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
#   JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
#   M2_HOME - location of maven2's installed home dir
#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
#     e.g. to debug Maven itself, use
#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------

if [ -z "$MAVEN_SKIP_RC" ] ; then

  if [ -f /etc/mavenrc ] ; then
    . /etc/mavenrc
  fi

  if [ -f "$HOME/.mavenrc" ] ; then
    . "$HOME/.mavenrc"
  fi

fi

# OS specific support.  $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
  CYGWIN*) cygwin=true ;;
  MINGW*) mingw=true;;
  Darwin*) darwin=true
    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
    if [ -z "$JAVA_HOME" ]; then
      if [ -x "/usr/libexec/java_home" ]; then
        export JAVA_HOME="`/usr/libexec/java_home`"
      else
        export JAVA_HOME="/Library/Java/Home"
      fi
    fi
    ;;
esac

if [ -z "$JAVA_HOME" ] ; then
  if [ -r /etc/gentoo-release ] ; then
    JAVA_HOME=`java-config --jre-home`
  fi
fi

if [ -z "$M2_HOME" ] ; then
  ## resolve links - $0 may be a link to maven's home
  PRG="$0"

  # need this for relative symlinks
  while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
      PRG="$link"
    else
      PRG="`dirname "$PRG"`/$link"
    fi
  done

  saveddir=`pwd`

  M2_HOME=`dirname "$PRG"`/..

  # make it fully qualified
  M2_HOME=`cd "$M2_HOME" && pwd`

  cd "$saveddir"
  # echo Using m2 at $M2_HOME
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --unix "$M2_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
  [ -n "$M2_HOME" ] &&
    M2_HOME="`(cd "$M2_HOME"; pwd)`"
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
  # TODO classpath?
fi

if [ -z "$JAVA_HOME" ]; then
  javaExecutable="`which javac`"
  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
    # readlink(1) is not available as standard on Solaris 10.
    readLink=`which readlink`
    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
      if $darwin ; then
        javaHome="`dirname \"$javaExecutable\"`"
        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
      else
        javaExecutable="`readlink -f \"$javaExecutable\"`"
      fi
      javaHome="`dirname \"$javaExecutable\"`"
      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
      JAVA_HOME="$javaHome"
      export JAVA_HOME
    fi
  fi
fi

if [ -z "$JAVACMD" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  else
    JAVACMD="`which java`"
  fi
fi

if [ ! -x "$JAVACMD" ] ; then
  echo "Error: JAVA_HOME is not defined correctly." >&2
  echo "  We cannot execute $JAVACMD" >&2
  exit 1
fi

if [ -z "$JAVA_HOME" ] ; then
  echo "Warning: JAVA_HOME environment variable is not set."
fi

CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher

# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {

  if [ -z "$1" ]
  then
    echo "Path not specified to find_maven_basedir"
    return 1
  fi

  basedir="$1"
  wdir="$1"
  while [ "$wdir" != '/' ] ; do
    if [ -d "$wdir"/.mvn ] ; then
      basedir=$wdir
      break
    fi
    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
    if [ -d "${wdir}" ]; then
      wdir=`cd "$wdir/.."; pwd`
    fi
    # end of workaround
  done
  echo "${basedir}"
}

# concatenates all lines of a file
concat_lines() {
  if [ -f "$1" ]; then
    echo "$(tr -s '\n' ' ' < "$1")"
  fi
}

BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
  exit 1;
fi

##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
    if [ "$MVNW_VERBOSE" = true ]; then
      echo "Found .mvn/wrapper/maven-wrapper.jar"
    fi
else
    if [ "$MVNW_VERBOSE" = true ]; then
      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
    fi
    jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
    while IFS="=" read key value; do
      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
      esac
    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
    if [ "$MVNW_VERBOSE" = true ]; then
      echo "Downloading from: $jarUrl"
    fi
    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"

    if command -v wget > /dev/null; then
        if [ "$MVNW_VERBOSE" = true ]; then
          echo "Found wget ... using wget"
        fi
        wget "$jarUrl" -O "$wrapperJarPath"
    elif command -v curl > /dev/null; then
        if [ "$MVNW_VERBOSE" = true ]; then
          echo "Found curl ... using curl"
        fi
        curl -o "$wrapperJarPath" "$jarUrl"
    else
        if [ "$MVNW_VERBOSE" = true ]; then
          echo "Falling back to using Java to download"
        fi
        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
        if [ -e "$javaClass" ]; then
            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
                if [ "$MVNW_VERBOSE" = true ]; then
                  echo " - Compiling MavenWrapperDownloader.java ..."
                fi
                # Compiling the Java class
                ("$JAVA_HOME/bin/javac" "$javaClass")
            fi
            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
                # Running the downloader
                if [ "$MVNW_VERBOSE" = true ]; then
                  echo " - Running MavenWrapperDownloader.java ..."
                fi
                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
            fi
        fi
    fi
fi
##########################################################################################
# End of extension
##########################################################################################

export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
  echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --path --windows "$M2_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi

WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

exec "$JAVACMD" \
  $MAVEN_OPTS \
  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"


================================================
FILE: mvnw.cmd
================================================
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements.  See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership.  The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License.  You may obtain a copy of the License at
@REM
@REM    https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied.  See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------

@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM     e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------

@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%

@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")

@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre

@setlocal

set ERROR_CODE=0

@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal

@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome

echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error

:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init

echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error

@REM ==== END VALIDATION ====

:init

@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.

set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir

set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir

:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir

:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"

:endDetectBaseDir

IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig

@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%

:endReadAdditionalConfig

SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
	IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 
)

@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
    echo Found %WRAPPER_JAR%
) else (
    echo Couldn't find %WRAPPER_JAR%, downloading it ...
	echo Downloading from: %DOWNLOAD_URL%
    powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
    echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension

%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end

:error
set ERROR_CODE=1

:end
@endlocal & set ERROR_CODE=%ERROR_CODE%

if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost

@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause

if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%

exit /B %ERROR_CODE%


================================================
FILE: package.json
================================================
{
  "dependencies": {
    "antora": "3.2.0-alpha.6",
    "@antora/atlas-extension": "1.0.0-alpha.2",
    "@antora/collector-extension": "1.0.0-alpha.7",
    "@asciidoctor/tabs": "1.0.0-beta.6",
    "@springio/antora-extensions": "1.13.0",
    "@springio/asciidoctor-extensions": "1.0.0-alpha.11"
  }
}


================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

	<modelVersion>4.0.0</modelVersion>

	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-keyvalue</artifactId>
	<version>4.1.0-SNAPSHOT</version>

	<name>Spring Data KeyValue</name>

	<parent>
		<groupId>org.springframework.data.build</groupId>
		<artifactId>spring-data-parent</artifactId>
		<version>4.1.0-SNAPSHOT</version>
		<relativePath/>
	</parent>

	<properties>
		<springdata.commons>4.1.0-SNAPSHOT</springdata.commons>
		<mapdb>3.1.0</mapdb>
		<java-module-name>spring.data.keyvalue</java-module-name>
	</properties>

	<dependencies>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-commons</artifactId>
			<version>${springdata.commons}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
		</dependency>

		<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-collections</artifactId>
			<version>${querydsl}</version>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>org.mapdb</groupId>
			<artifactId>mapdb</artifactId>
			<version>${mapdb}</version>
			<scope>test</scope>
		</dependency>

	</dependencies>

	<build>
		<plugins>

			<plugin>
				<groupId>com.mysema.maven</groupId>
				<artifactId>apt-maven-plugin</artifactId>
				<version>${apt}</version>
				<executions>
					<execution>
						<phase>generate-test-sources</phase>
						<goals>
							<goal>test-process</goal>
						</goals>
						<configuration>
							<outputDirectory>target/generated-test-sources
							</outputDirectory>
							<processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor>
						</configuration>
					</execution>
				</executions>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-assembly-plugin</artifactId>
			</plugin>

		</plugins>
	</build>

	<profiles>
		<profile>
			<!-- placeholder for no profile -->
			<id>none</id>
		</profile>
		<profile>
			<id>antora-process-resources</id>
			<build>
				<resources>
					<resource>
						<directory>src/main/antora/resources/antora-resources</directory>
						<filtering>true</filtering>
					</resource>
				</resources>
			</build>
		</profile>
		<profile>
			<id>antora</id>
			<build>
				<plugins>
					<plugin>
						<groupId>org.antora</groupId>
						<artifactId>antora-maven-plugin</artifactId>
					</plugin>
				</plugins>
			</build>
		</profile>
	</profiles>

	<repositories>
		<repository>
			<id>spring-snapshot</id>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
			<releases>
				<enabled>false</enabled>
			</releases>
		</repository>
		<repository>
			<id>spring-milestone</id>
			<url>https://repo.spring.io/milestone</url>
		</repository>
	</repositories>

</project>


================================================
FILE: settings.xml
================================================
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">

	<servers>
		<server>
			<id>spring-plugins-release</id>
			<username>${env.ARTIFACTORY_USR}</username>
			<password>${env.ARTIFACTORY_PSW}</password>
		</server>
		<server>
			<id>spring-libs-snapshot</id>
			<username>${env.ARTIFACTORY_USR}</username>
			<password>${env.ARTIFACTORY_PSW}</password>
		</server>
		<server>
			<id>spring-libs-milestone</id>
			<username>${env.ARTIFACTORY_USR}</username>
			<password>${env.ARTIFACTORY_PSW}</password>
		</server>
		<server>
			<id>spring-libs-release</id>
			<username>${env.ARTIFACTORY_USR}</username>
			<password>${env.ARTIFACTORY_PSW}</password>
		</server>
	</servers>

</settings>

================================================
FILE: src/main/antora/antora-playbook.yml
================================================
# PACKAGES antora@3.2.0-alpha.2 @antora/atlas-extension:1.0.0-alpha.1 @antora/collector-extension@1.0.0-alpha.3 @springio/antora-extensions@1.1.0-alpha.2 @asciidoctor/tabs@1.0.0-alpha.12 @opendevise/antora-release-line-extension@1.0.0-alpha.2
#
# The purpose of this Antora playbook is to build the docs in the current branch.
antora:
  extensions:
    - require: '@springio/antora-extensions'
      root_component_name: 'data-keyvalue'
site:
  title: Spring Data KeyValue
  url: https://docs.spring.io/spring-data/keyvalue/reference/
content:
  sources:
    - url: ./../../..
      branches: HEAD
      start_path: src/main/antora
      worktrees: true
    - url: https://github.com/spring-projects/spring-data-commons
      # Refname matching:
      # https://docs.antora.org/antora/latest/playbook/content-refname-matching/
      branches: [ main ]
      start_path: src/main/antora
asciidoc:
  attributes:
    hide-uri-scheme: '@'
    tabs-sync-option: '@'
  extensions:
    - '@asciidoctor/tabs'
    - '@springio/asciidoctor-extensions'
    - '@springio/asciidoctor-extensions/javadoc-extension'
  sourcemap: true
urls:
  latest_version_segment: ''
runtime:
  log:
    failure_level: warn
    format: pretty
ui:
  bundle:
    url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.16/ui-bundle.zip
    snapshot: true


================================================
FILE: src/main/antora/antora.yml
================================================
name: data-keyvalue
version: true
title: Spring Data KeyValue
nav:
  - modules/ROOT/nav.adoc
ext:
  collector:
    - run:
        command: ./mvnw validate process-resources dependency:unpack -am -Pantora-process-resources
        local: true
      scan:
        - dir: target/classes/
        - dir: target/antora/


================================================
FILE: src/main/antora/modules/ROOT/nav.adoc
================================================
* xref:index.adoc[Overview]
* xref:keyvalue.adoc[]
* xref:keyvalue/template.adoc[]

* xref:repositories.adoc[]
** xref:repositories/core-concepts.adoc[]
** xref:repositories/definition.adoc[]
** xref:repositories/create-instances.adoc[]
** xref:keyvalue/repository/map-repositories.adoc[]
** xref:keyvalue/value-expressions.adoc[]
** xref:repositories/query-keywords-reference.adoc[]
** xref:repositories/query-return-types-reference.adoc[]

* xref:attachment$api/java/index.html[Javadoc,role=link-external,window=_blank]
* https://github.com/spring-projects/spring-data-commons/wiki[Wiki,role=link-external,window=_blank]



================================================
FILE: src/main/antora/modules/ROOT/pages/commons/upgrade.adoc
================================================
include::{commons}@data-commons::page$upgrade.adoc[]

Once you’ve decided to upgrade your application, you can find detailed information regarding specific features in the rest of the document.

Spring Data's documentation is specific to that version, so any information that you find in here will contain the most up-to-date changes that are in that version.


================================================
FILE: src/main/antora/modules/ROOT/pages/index.adoc
================================================
[[spring-data-key-value-reference-guide]]
= Spring Data Key-Value
:revnumber: {version}
:revdate: {localdate}
:feature-scroll: true

Spring Data KeyValue provides connectivity and repository support for the in memory map structures.
It eases development of applications with a consistent programming model that need to access key based storage and servers as foundation for custom adapters._

[horizontal]
xref:keyvalue.adoc[Key/Value Storage] :: Support for built in key-value structures
xref:repositories.adoc[Repositories] :: KeyValue Repositories
https://github.com/spring-projects/spring-data-commons/wiki[Wiki] :: What's New, Upgrade Notes, Supported Versions, additional cross-version information.

Oliver Gierke; Thomas Darimont; Christoph Strobl; Jay Bryant; Mark Paluch

(C) 2008-{copyright-year} VMware, Inc.

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.


================================================
FILE: src/main/antora/modules/ROOT/pages/keyvalue/repository/map-repositories.adoc
================================================
[[key-value.repositories.map]]
= Map Repositories

Map repositories reside on top of the `KeyValueTemplate`.
Using the default `PredicateQueryCreator` allows deriving query and sort expressions from the given method name, as the following example shows:

[source, java]
----
@Configuration
@EnableMapRepositories
class KeyValueConfig {

}

interface PersonRepository implements CrudRepository<Person, String> {
    List<Person> findByLastname(String lastname);
}
----

== Configuring the QueryEngine

It is possible to change the `QueryEngine` and use a custom one instead of the default.
The `EnableMapRepositories` annotation allows to configure the by supplying a `QueryEngineFactory` as well as the `QueryCreator` via according attributes.
Please mind that the `QueryEngine` needs to be able to process queries created by the configured `QueryCreator`.

== Storage Backend Configuration

`KeySpaceStore` provides a simple storage facade that can be used along with the `keySpaceStoreRef` attribute of `EnableMapRepositories` to set the bean reference to the actual storage, overriding `mapType` settings.

====
[source,java]
----
@Configuration
@EnableMapRepositories(keySpaceStoreRef = "store") <1>
public class MapDbConfiguration {

	@Bean
	KeySpaceStore store(DB db) { <1>

		return new KeySpaceStore() {

			@Override
			public Map<Object, Object> getKeySpace(String keyspace) {
				return db.hashMap(keyspace, ...
			}

			@Override
			public void clear() {
				//
			}

		};
	}

}
----
<1> reference the `KeySpaceStore` by bean name.
====


================================================
FILE: src/main/antora/modules/ROOT/pages/keyvalue/template.adoc
================================================
[[key-value.template]]
= Template API

In its very basic shape, the `KeyValueTemplate` uses a `MapAdapter` that wraps a `ConcurrentHashMap` and that uses link:{spring-framework-docs}/core/expressions.html[Spring Expression Language] to run queries and sorting.

NOTE: The used `KeyValueAdapter` does the heavy lifting when it comes to storing and retrieving data.
The data structure influences performance and multi-threading behavior.

You can use a different type or pre-initialize the adapter with some values, and you can do so by using various constructors on `MapKeyValueAdapter`, as the following example shows:

====
[source, java]
----
@Configuration
class MyConfiguration {

  @Bean
  public KeyValueOperations mapKeyValueTemplate() {               <1>
    return new KeyValueTemplate(keyValueAdapter());
  }

  @Bean
  public KeyValueAdapter keyValueAdapter() {
    return new MapKeyValueAdapter(ConcurrentHashMap.class);       <2>
  }
}
----
<1> Defines a custom `KeyValueOperations` bean using the default bean name. See documentation and properties of `@EnableMapRepositories` for further customization.
<2> Defines a custom `KeyValueAdapter` bean using a `ConcurrentHashMap` as storage that is used by `KeyValueTemplate`.
====

[[key-value.keyspaces]]
== Keyspaces

The following example shows a keyspace for a repository of `Person` objects:

====
[source, java]
----
@KeySpace("persons")
class Person {

  @Id String id;
  String firstname;
  String lastname;
}

class User extends Person {
  String username;
}

template.findAllOf(Person.class); <1>
template.findAllOf(User.class);   <2>
----
<1> Returns all entities for the `persons` keyspace.
<2> Returns only elements of type `User` stored in `persons` keyspace.
====

TIP: `@KeySpace` supports xref:keyvalue/value-expressions.adoc[Value Expressions] allowing dynamic keyspace configuration.

[[key-value.keyspaces-custom]]
=== Custom KeySpace Annotation

You can compose your own `KeySpace` annotations for a more domain-centric usage by annotating one of the attributes with `@AliasFor`.

IMPORTANT: The composed annotation must inherit `@Persistent`.

The following example shows a custom `@KeySpace` annotation:

====
[source, java]
----
@KeySpace
@Persistent
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
static @interface CacheCentricAnnotation {

  @AliasFor(annotation = KeySpace.class, attribute = "value")
  String cacheRegion() default "";
}

@CacheCentricAnnotation(cacheRegion = "customers")
class Customer {
  //...
}
----
====

[[key-value.template-query]]
== Querying

Running queries is managed by a `QueryEngine`.
As mentioned earlier, you can instruct the `KeyValueAdapter` to use an implementation-specific `QueryEngine` that allows access to native functionality.
When used without further customization, queries can be run by using `SpELQueryEngine`.

NOTE: For performance reasons, we highly recommend to make use of link:{spring-framework-docs}/core/expressions/evaluation.html#expressions-compiler-configuration[compiled SpEL Expressions].
("`SpEL`" is short for "`Spring Expression Language`".) You can use the `-Dspring.expression.compiler.mode=IMMEDIATE` switch to enable it.

The following example shows a query that uses the SpEL:

====
[source,java]
----
KeyValueQuery<String> query = new KeyValueQuery<String>("lastname == 'targaryen'");
List<Person> targaryens = template.find(query, Person.class);
----
====

IMPORTANT: You must have getters and setters present to query properties when you use SpEL.

[[key-value.template-sort]]
== Sorting

Depending on the store implementation provided by the adapter, entities might already be stored in some sorted way but do not necessarily have to be.Again, the underlying `QueryEngine` is capable of performing sort operations.
When used without further customization, sorting is done by using a `SpelPropertyComparator` extracted from the `Sort` clause.The following example shows a query with a `Sort` clause:

====
[source, java]
----
KeyValueQuery<String> query = new KeyValueQuery<String>("lastname == 'baratheon'");
query.setSort(Sort.by(DESC, "age"));
List<Person> targaryens = template.find(query, Person.class);
----
====

IMPORTANT: Please note that you need to have getters and setters present to sort using SpEL.


================================================
FILE: src/main/antora/modules/ROOT/pages/keyvalue/value-expressions.adoc
================================================
include::{commons}@data-commons::page$value-expressions.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/keyvalue.adoc
================================================
[[key-value]]
= KeyValue

Spring Data KeyValue provides easy configuration and access to `Map` like structures that associate values with unique keys.
It offers both low-level and high-level abstractions for interacting with the underlying data structure, freeing the user from infrastructural concerns.

The key-value abstraction within Spring Data Key Value requires an `Adapter` that shields the native store implementation, freeing up `KeyValueTemplate` to work on top of any key-value pair-like structure.
Keys are distributed across <<key-value.keyspaces,Keyspaces>>.
Unless otherwise specified, the class name is used as the default keyspace for an entity.
The following interface definition shows the `KeyValueOperations` interface, which is the heart of Spring Data Key-Value:

====
[source, java]
----
interface KeyValueOperations {

    <T> T insert(T objectToInsert);                               <1>

    void update(Object objectToUpdate);                           <2>

    void delete(Class<?> type);                                   <3>

    <T> T findById(Object id, Class<T> type);                     <4>

    <T> Iterable<T> findAllOf(Class<T> type);                     <5>

    <T> Iterable<T> find(KeyValueQuery<?> query, Class<T> type);  <6>

    //... more functionality omitted.

}
----
<1> Inserts the given entity and assigns an ID (if required).
<2> Updates the given entity.
<3> Removes all entities of the matching type.
<4> Returns the entity of the given type with its matching ID.
<5> Returns all entities of the matching type.
<6> Returns a `List` of all entities of the given type that match the criteria of the query.
====

[[key-value.keyspaces]]
== Keyspaces

Keyspaces define the part of the data structure in which the entity should be kept.
This concept is similar to collections in MongoDB and Elasticsearch, cores in Solr, and tables in JPA.
By default, the keyspace of an entity is extracted from its type, but you can also store entities of different types within one keyspace.


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/core-concepts.adoc
================================================
include::{commons}@data-commons::page$repositories/core-concepts.adoc[]

[[redis.entity-persistence.state-detection-strategies]]
include::{commons}@data-commons::page$is-new-state-detection.adoc[leveloffset=+1]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/core-domain-events.adoc
================================================
include::{commons}@data-commons::page$repositories/core-domain-events.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc
================================================
[[core.extensions.querydsl]]
= Querydsl

Spring Data Redis does not support Querydsl.


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/create-instances.adoc
================================================
include::{commons}@data-commons::page$repositories/create-instances.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/custom-implementations.adoc
================================================
include::{commons}@data-commons::page$repositories/custom-implementations.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/definition.adoc
================================================
include::{commons}@data-commons::page$repositories/definition.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/null-handling.adoc
================================================
include::{commons}@data-commons::page$repositories/null-handling.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/object-mapping.adoc
================================================
include::{commons}@data-commons::page$object-mapping.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/projections.adoc
================================================
[[cassandra.projections]]
= Projections

include::{commons}@data-commons::page$repositories/projections.adoc[leveloffset=+1]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/query-keywords-reference.adoc
================================================
include::{commons}@data-commons::page$repositories/query-keywords-reference.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/query-methods-details.adoc
================================================
include::{commons}@data-commons::page$repositories/query-methods-details.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories/query-return-types-reference.adoc
================================================
include::{commons}@data-commons::page$repositories/query-return-types-reference.adoc[]


================================================
FILE: src/main/antora/modules/ROOT/pages/repositories.adoc
================================================
[[keyvalyue.repositories]]
= KeyValue Repositories

This chapter explains the basic foundations of Spring Data repositories and KeyValue specifics.
Before continuing to the specifics, make sure you have a sound understanding of the basic concepts.

The goal of the Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.


================================================
FILE: src/main/antora/resources/antora-resources/antora.yml
================================================
version: ${antora-component.version}
prerelease: ${antora-component.prerelease}

asciidoc:
  attributes:
    attribute-missing: 'warn'
    chomp: 'all'
    version: '${project.version}'
    copyright-year: '${current.year}'
    springversionshort: '${spring.short}'
    springversion: '${spring}'
    commons: '${springdata.commons.docs}'
    include-xml-namespaces: false
    spring-data-commons-docs-url: '${documentation.baseurl}/spring-data/commons/reference/${springdata.commons.short}'
    spring-data-commons-javadoc-base: '{spring-data-commons-docs-url}/api/java'
    springdocsurl: '${documentation.baseurl}/spring-framework/reference/{springversionshort}'
    spring-framework-docs: '{springdocsurl}'
    springjavadocurl: '${documentation.spring-javadoc-url}'
    spring-framework-javadoc: '{springjavadocurl}'
    springhateoasversion: '${spring-hateoas}'
    releasetrainversion: '${releasetrain}'
    store: KeyValue


================================================
FILE: src/main/java/org/springframework/data/keyvalue/annotation/KeySpace.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.annotation;

import static java.lang.annotation.ElementType.*;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.data.annotation.Persistent;

/**
 * Marker interface for methods with {@link Persistent} annotations indicating the presence of a dedicated keyspace the
 * entity should reside in. If present the value will be picked up for resolving the keyspace. The {@link #value()}
 * attribute supports Value Expressions to dynamically resolve the keyspace based on a per-operation basis.
 *
 * <pre class="code">
 * &#64;Persistent
 * &#64;Retention(RetentionPolicy.RUNTIME)
 * &#64;Target({ ElementType.TYPE })
 * static @interface CacheCentricAnnotation {
 *
 * 	&#64;AliasFor(annotation = KeySpace.class, attribute = "value")
 * 	String cacheRegion() default "";
 * }
 *
 * &#64;CacheCentricAnnotation(cacheRegion = "customers")
 * class Customer {
 * 	// ...
 * }
 * </pre>
 *
 * Can also be directly used on types to indicate the keyspace.
 *
 * <pre class="code">
 * &#64;KeySpace("persons")
 * public class Foo {
 *
 * }
 * </pre>
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { METHOD, TYPE })
public @interface KeySpace {

	/**
	 * @return dedicated keyspace the entity should reside in.
	 */
	String value() default "";
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/annotation/package-info.java
================================================
/**
 * Key-Value annotations for declarative keyspace configuration.
 */
@org.jspecify.annotations.NullMarked
package org.springframework.data.keyvalue.annotation;


================================================
FILE: src/main/java/org/springframework/data/keyvalue/aot/KeyValueRuntimeHints.java
================================================
/*
 * Copyright 2022-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.aot;

import java.util.Arrays;
import java.util.List;

import org.jspecify.annotations.Nullable;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery;

/**
 * {@link RuntimeHintsRegistrar} for KeyValue.
 *
 * @author Christoph Strobl
 * @since 3.0
 */
class KeyValueRuntimeHints implements RuntimeHintsRegistrar {

	@Override
	public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {

		// REFLECTION
		hints.reflection().registerTypes(
				Arrays.asList(
						TypeReference.of(org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository.class),
						TypeReference.of(KeyValuePartTreeQuery.class)),
				hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS));

		hints.reflection().registerType(TypeReference.of("java.util.Comparators.NaturalOrderComparator"),
				builder -> builder.withMethod("compare",
						List.of(TypeReference.of(Object.class), TypeReference.of(Object.class)), ExecutableMode.INVOKE));

		hints.reflection().registerType(TypeReference.of("java.util.Comparators.NullComparator"),
				builder -> builder.withMethod("compare",
						List.of(TypeReference.of(Object.class), TypeReference.of(Object.class)), ExecutableMode.INVOKE));
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/aot/package-info.java
================================================
/**
 * Support classes for key-value ahead of time computation
 */
@org.jspecify.annotations.NullMarked
package org.springframework.data.keyvalue.aot;


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/AbstractKeyValueAdapter.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Collection;
import java.util.Comparator;

import org.jspecify.annotations.Nullable;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;

/**
 * Base implementation of {@link KeyValueAdapter} holds {@link QueryEngine} to delegate {@literal find} and
 * {@literal count} execution to.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 */
public abstract class AbstractKeyValueAdapter implements KeyValueAdapter {

	private final QueryEngine<? extends KeyValueAdapter, ?, ?> engine;

	/**
	 * Creates new {@link AbstractKeyValueAdapter} with using the default query engine.
	 */
	protected AbstractKeyValueAdapter() {
		this((QueryEngine<? extends KeyValueAdapter, ?, ?>) null);
	}

	/**
	 * Creates new {@link AbstractKeyValueAdapter} with using the default query engine and provided comparator for sorting.
	 *
	 * @param sortAccessor must not be {@literal null}.
	 * @since 3.1.10
	 */
	protected AbstractKeyValueAdapter(SortAccessor<Comparator<?>> sortAccessor) {
		this(new PredicateQueryEngine(sortAccessor));
	}

	/**
	 * Creates new {@link AbstractKeyValueAdapter} with using the default query engine.
	 *
	 * @param engine will be defaulted to {@link SpelQueryEngine} if {@literal null}.
	 */
	protected AbstractKeyValueAdapter(@Nullable QueryEngine<? extends KeyValueAdapter, ?, ?> engine) {

		this.engine = engine != null ? engine : new PredicateQueryEngine();
		this.engine.registerAdapter(this);
	}

	/**
	 * Get the {@link QueryEngine} used.
	 *
	 * @return
	 */
	protected QueryEngine<? extends KeyValueAdapter, ?, ?> getQueryEngine() {
		return engine;
	}

	@Override
	public <T> @Nullable T get(Object id, String keyspace, Class<T> type) {
		return type.cast(get(id, keyspace));
	}

	@Override
	public <T> @Nullable T delete(Object id, String keyspace, Class<T> type) {
		return type.cast(delete(id, keyspace));
	}

	@Override
	public <T> Iterable<T> find(KeyValueQuery<?> query, String keyspace, Class<T> type) {
		return engine.execute(query, keyspace, type);
	}

	@Override
	public Collection<?> find(KeyValueQuery<?> query, String keyspace) {
		return engine.execute(query, keyspace);
	}

	@Override
	public long count(KeyValueQuery<?> query, String keyspace) {
		return engine.count(query, keyspace);
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/CriteriaAccessor.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.jspecify.annotations.Nullable;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;

/**
 * Resolves the criteria object from given {@link KeyValueQuery}.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 * @param <T>
 */
public interface CriteriaAccessor<T> {

	/**
	 * Checks and reads {@link KeyValueQuery#getCriteria()} of given {@link KeyValueQuery}. Might also apply additional
	 * transformation to match the desired type.
	 *
	 * @param query must not be {@literal null}.
	 * @return the criteria extracted from the query. Can be {@literal null}.
	 * @throws IllegalArgumentException in case the criteria is not valid for usage with specific
	 *           {@link CriteriaAccessor}.
	 */
	@Nullable
	T resolve(KeyValueQuery<?> query);
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/DefaultIdentifierGenerator.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;

import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.core.TypeInformation;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

/**
 * Default implementation of {@link IdentifierGenerator} to generate identifiers of types {@link UUID}, String,
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 */
enum DefaultIdentifierGenerator implements IdentifierGenerator {

	INSTANCE;

	private final AtomicReference<SecureRandom> secureRandom = new AtomicReference<>(null);

	@Override
	@SuppressWarnings("unchecked")
	public <T> T generateIdentifierOfType(TypeInformation<T> identifierType) {

		Class<?> type = identifierType.getType();

		if (ClassUtils.isAssignable(UUID.class, type)) {
			return (T) UUID.randomUUID();
		} else if (ClassUtils.isAssignable(String.class, type)) {
			return (T) UUID.randomUUID().toString();
		} else if (ClassUtils.isAssignable(Integer.class, type)) {
			return (T) Integer.valueOf(getSecureRandom().nextInt());
		} else if (ClassUtils.isAssignable(Long.class, type)) {
			return (T) Long.valueOf(getSecureRandom().nextLong());
		}

		throw new InvalidDataAccessApiUsageException(
				String.format("Identifier cannot be generated for %s; Supported types are: UUID, String, Integer, and Long",
						identifierType.getType().getName()));
	}

	private SecureRandom getSecureRandom() {

		SecureRandom secureRandom = this.secureRandom.get();
		if (secureRandom != null) {
			return secureRandom;
		}

		for (String algorithm : OsTools.secureRandomAlgorithmNames()) {
			try {
				secureRandom = SecureRandom.getInstance(algorithm);
			} catch (NoSuchAlgorithmException e) {
				// ignore and try next.
			}
		}

		if (secureRandom == null) {
			throw new InvalidDataAccessApiUsageException(
					String.format("Could not create SecureRandom instance for one of the algorithms '%s'",
							StringUtils.collectionToCommaDelimitedString(OsTools.secureRandomAlgorithmNames())));
		}

		this.secureRandom.compareAndSet(null, secureRandom);

		return secureRandom;
	}

	/**
	 * @author Christoph Strobl
	 * @since 1.1.2
	 */
	private static class OsTools {

		private static final String OPERATING_SYSTEM_NAME = System.getProperty("os.name").toLowerCase();

		private static final List<String> SECURE_RANDOM_ALGORITHMS_LINUX_OSX_SOLARIS = Arrays.asList("NativePRNGBlocking",
				"NativePRNGNonBlocking", "NativePRNG", "SHA1PRNG");
		private static final List<String> SECURE_RANDOM_ALGORITHMS_WINDOWS = Arrays.asList("SHA1PRNG", "Windows-PRNG");

		static List<String> secureRandomAlgorithmNames() {
			return OPERATING_SYSTEM_NAME.contains("win") ? SECURE_RANDOM_ALGORITHMS_WINDOWS
					: SECURE_RANDOM_ALGORITHMS_LINUX_OSX_SOLARIS;
		}
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/ForwardingCloseableIterator.java
================================================
/*
 * Copyright 2015-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Iterator;

import org.jspecify.annotations.Nullable;
import org.springframework.data.util.CloseableIterator;
import org.springframework.util.Assert;

/**
 * Forwards {@link CloseableIterator} invocations to the configured {@link Iterator} delegate.
 *
 * @author Christoph Strobl
 * @author Thomas Darimont
 * @author Oliver Gierke
 * @author Mark Paluch
 */
public class ForwardingCloseableIterator<T> implements CloseableIterator<T> {

	private final Iterator<? extends T> delegate;
	private final @Nullable Runnable closeHandler;

	/**
	 * Creates a new {@link ForwardingCloseableIterator}.
	 *
	 * @param delegate must not be {@literal null}.
	 */
	public ForwardingCloseableIterator(Iterator<? extends T> delegate) {
		this(delegate, null);
	}

	/**
	 * Creates a new {@link ForwardingCloseableIterator} that invokes the configured {@code closeHandler} on
	 * {@link #close()}.
	 *
	 * @param delegate must not be {@literal null}.
	 * @param closeHandler may be {@literal null}.
	 */
	public ForwardingCloseableIterator(Iterator<? extends T> delegate, @Nullable Runnable closeHandler) {

		Assert.notNull(delegate, "Delegate iterator must not be null");

		this.delegate = delegate;
		this.closeHandler = closeHandler;
	}

	@Override
	public boolean hasNext() {
		return delegate.hasNext();
	}

	@Override
	public T next() {
		return delegate.next();
	}

	@Override
	public void close() {
		if (closeHandler != null) {
			closeHandler.run();
		}
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/GeneratingIdAccessor.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.jspecify.annotations.Nullable;
import org.springframework.data.mapping.IdentifierAccessor;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.util.Assert;

/**
 * {@link IdentifierAccessor} adding a {@link #getOrGenerateIdentifier()} to automatically generate an identifier and
 * set it on the underling bean instance.
 *
 * @author Oliver Gierke
 * @author Mark Paluch
 * @see #getOrGenerateIdentifier()
 */
class GeneratingIdAccessor implements IdentifierAccessor {

	private final PersistentPropertyAccessor<?> accessor;
	private final PersistentProperty<?> identifierProperty;
	private final IdentifierGenerator generator;

	/**
	 * Creates a new {@link GeneratingIdAccessor} using the given {@link PersistentPropertyAccessor}, identifier property
	 * and {@link IdentifierGenerator}.
	 *
	 * @param accessor must not be {@literal null}.
	 * @param identifierProperty must not be {@literal null}.
	 * @param generator must not be {@literal null}.
	 */
	GeneratingIdAccessor(PersistentPropertyAccessor<?> accessor, PersistentProperty<?> identifierProperty,
			IdentifierGenerator generator) {

		Assert.notNull(accessor, "PersistentPropertyAccessor must not be null");
		Assert.notNull(identifierProperty, "Identifier property must not be null");
		Assert.notNull(generator, "IdentifierGenerator must not be null");

		this.accessor = accessor;
		this.identifierProperty = identifierProperty;
		this.generator = generator;
	}

	@Override
	public @Nullable Object getIdentifier() {
		return accessor.getProperty(identifierProperty);
	}

	/**
	 * Returns the identifier value of the backing bean or generates a new one using the configured
	 * {@link IdentifierGenerator}.
	 *
	 * @return
	 */
	Object getOrGenerateIdentifier() {

		Object existingIdentifier = getIdentifier();

		if (existingIdentifier != null) {
			return existingIdentifier;
		}

		Object generatedIdentifier = generator.generateIdentifierOfType(identifierProperty.getTypeInformation());
		accessor.setProperty(identifierProperty, generatedIdentifier);

		return generatedIdentifier;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/IdentifierGenerator.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.springframework.data.core.TypeInformation;

/**
 * API for components generating identifiers.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 */
public interface IdentifierGenerator {

	/**
	 * Creates an identifier of the given type.
	 *
	 * @param type must not be {@literal null}.
	 * @return an identifier of the given type.
	 */
	<T> T generateIdentifierOfType(TypeInformation<T> type);
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/IterableConverter.java
================================================
/*
 * Copyright 2015-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.jspecify.annotations.Nullable;
import org.springframework.lang.Contract;

/**
 * Converter capable of transforming a given {@link Iterable} into a collection type.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 */
public final class IterableConverter {

	private IterableConverter() {}

	/**
	 * Converts a given {@link Iterable} into a {@link List}
	 *
	 * @param source
	 * @return {@link Collections#emptyList()} when source is {@literal null}.
	 */
	@Contract("_ -> !null")
	public static <T> List<T> toList(@Nullable Iterable<T> source) {

		if(source == null) {
			return Collections.emptyList();
		}

		if (source instanceof List) {
			return (List<T>) source;
		}

		if (source instanceof Collection) {
			return new ArrayList<>((Collection<T>) source);
		}

		List<T> result = new ArrayList<>();
		for (T value : source) {
			result.add(value);
		}
		return result;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Collection;
import java.util.Map;

import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.util.CloseableIterator;

/**
 * {@link KeyValueAdapter} unifies access and shields the underlying key/value specific implementation.
 *
 * @author Christoph Strobl
 * @author Thomas Darimont
 * @author Mark Paluch
 */
public interface KeyValueAdapter extends DisposableBean {

	/**
	 * Add object with given id to keyspace.
	 *
	 * @param id must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @return the item previously associated with the id.
	 */
	@Nullable Object put(Object id, Object item, String keyspace);

	/**
	 * Check if a object with given id exists in keyspace.
	 *
	 * @param id must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @return true if item of type with id exists.
	 */
	boolean contains(Object id, String keyspace);

	/**
	 * Get the object with given id from keyspace.
	 *
	 * @param id must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @return {@literal null} in case no matching item exists.
	 */
	@Nullable
	Object get(Object id, String keyspace);

	/**
	 * Get the object with given id from keyspace.
	 *
	 * @param id must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return {@literal null} in case no matching item exists.
	 * @since 1.1
	 */
	<T> @Nullable T get(Object id, String keyspace, Class<T> type);

	/**
	 * Delete and return the object with given type and id.
	 *
	 * @param id must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @return {@literal null} if object could not be found
	 */
	@Nullable
	Object delete(Object id, String keyspace);

	/**
	 * Delete and return the object with given type and id.
	 *
	 * @param id must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return {@literal null} if object could not be found
	 * @since 1.1
	 */
	<T> @Nullable T delete(Object id, String keyspace, Class<T> type);

	/**
	 * Get all elements for given keyspace.
	 *
	 * @param keyspace must not be {@literal null}.
	 * @return empty {@link Collection} if nothing found.
	 */
	Iterable<Object> getAllOf(String keyspace);

	/**
	 * Get all elements for given keyspace.
	 *
	 * @param keyspace must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return empty {@link Collection} if nothing found.
	 * @since 2.5
	 */
	@SuppressWarnings("unchecked")
	default <T> Iterable<T> getAllOf(String keyspace, Class<T> type) {
		return (Iterable<T>) getAllOf(keyspace);
	}

	/**
	 * Returns a {@link CloseableIterator} that iterates over all entries.
	 *
	 * @param keyspace must not be {@literal null}.
	 * @return
	 */
	CloseableIterator<Map.Entry<Object, Object>> entries(String keyspace);

	/**
	 * Returns a {@link CloseableIterator} that iterates over all entries.
	 *
	 * @param keyspace must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return
	 * @since 2.5
	 */
	@SuppressWarnings("unchecked")
	default <T> CloseableIterator<Map.Entry<Object,T>> entries(String keyspace, Class<T> type) {
		return (CloseableIterator) entries(keyspace);
	}

	/**
	 * Remove all objects of given type.
	 *
	 * @param keyspace must not be {@literal null}.
	 */
	void deleteAllOf(String keyspace);

	/**
	 * Removes all objects.
	 */
	void clear();

	/**
	 * Find all matching objects within {@literal keyspace}.
	 *
	 * @param query must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @return empty {@link Collection} if no match found.
	 */
	default Iterable<?> find(KeyValueQuery<?> query, String keyspace) {
		return find(query, keyspace, Object.class);
	}

	/**
	 * @param query must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return empty {@link Collection} if no match found.
	 * @since 1.1
	 */
	<T> Iterable<T> find(KeyValueQuery<?> query, String keyspace, Class<T> type);

	/**
	 * Count number of objects within {@literal keyspace}.
	 *
	 * @param keyspace must not be {@literal null}.
	 * @return
	 */
	long count(String keyspace);

	/**
	 * Count all matching objects within {@literal keyspace}.
	 *
	 * @param query must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @return
	 */
	long count(KeyValueQuery<?> query, String keyspace);

	/**
	 * Determine whether result of given {@link KeyValueQuery} within {@literal keyspace} contains at least one element.
	 *
	 * @param query must not be {@literal null}.
	 * @param keyspace must not be {@literal null}.
	 * @return
	 * @since 2.7
	 */
	default boolean exists(KeyValueQuery<?> query, String keyspace) {
		return count(query, keyspace) > 0;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValueCallback.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.jspecify.annotations.Nullable;

/**
 * Generic callback interface for code that operates on a {@link KeyValueAdapter}. This is particularly useful for
 * delegating code that needs to work closely on the underlying key/value store implementation.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 * @param <T>
 */
public interface KeyValueCallback<T> {

	/**
	 * Gets called by {@code KeyValueTemplate#execute(KeyValueCallback)}. Allows for returning a result object created
	 * within the callback, i.e. a domain object or a collection of domain objects.
	 *
	 * @param adapter
	 * @return
	 */
	@Nullable
	T doInKeyValue(KeyValueAdapter adapter);
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Optional;

import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.data.domain.Sort;
import org.springframework.data.keyvalue.annotation.KeySpace;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.mapping.context.MappingContext;

/**
 * Interface that specifies a basic set of key/value operations. Implemented by {@link KeyValueTemplate}.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 */
public interface KeyValueOperations extends DisposableBean {

	/**
	 * Add given object. Object needs to have id property to which a generated value will be assigned.
	 *
	 * @param objectToInsert
	 * @return the inserted object.
	 */
	<T> T insert(T objectToInsert);

	/**
	 * Add object with given id.
	 *
	 * @param id must not be {@literal null}.
	 * @param objectToInsert must not be {@literal null}.
	 * @return the inserted object.
	 */
	<T> T insert(Object id, T objectToInsert);

	/**
	 * Get all elements of given type. Respects {@link KeySpace} if present and therefore returns all elements that can be
	 * assigned to requested type.
	 *
	 * @param type must not be {@literal null}.
	 * @return empty iterable if no elements found.
	 */
	<T> Iterable<T> findAll(Class<T> type);

	/**
	 * Get all elements ordered by sort. Respects {@link KeySpace} if present and therefore returns all elements that can
	 * be assigned to requested type.
	 *
	 * @param sort must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return
	 */
	<T> Iterable<T> findAll(Sort sort, Class<T> type);

	/**
	 * Get element of given type with given id. Respects {@link KeySpace} if present and therefore returns all elements
	 * that can be assigned to requested type.
	 *
	 * @param id must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return {@link Optional#empty()} if not found.
	 */
	<T> Optional<T> findById(Object id, Class<T> type);

	/**
	 * Execute operation against underlying store.
	 *
	 * @param action must not be {@literal null}.
	 * @return
	 */

	<T> @Nullable T execute(KeyValueCallback<T> action);

	/**
	 * Get all elements matching the given query. <br />
	 * Respects {@link KeySpace} if present and therefore returns all elements that can be assigned to requested type..
	 *
	 * @param query must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return empty iterable if no match found.
	 */
	<T> Iterable<T> find(KeyValueQuery<?> query, Class<T> type);

	/**
	 * Get all elements in given range. Respects {@link KeySpace} if present and therefore returns all elements that can
	 * be assigned to requested type.
	 *
	 * @param offset
	 * @param rows
	 * @param type must not be {@literal null}.
	 * @return
	 */
	<T> Iterable<T> findInRange(long offset, int rows, Class<T> type);

	/**
	 * Get all elements in given range ordered by sort. Respects {@link KeySpace} if present and therefore returns all
	 * elements that can be assigned to requested type.
	 *
	 * @param offset
	 * @param rows
	 * @param sort
	 * @param type
	 * @return
	 */
	<T> Iterable<T> findInRange(long offset, int rows, Sort sort, Class<T> type);

	/**
	 * @param objectToUpdate must not be {@literal null}.
	 * @return the updated object.
	 */
	<T> T update(T objectToUpdate);

	/**
	 * @param id must not be {@literal null}.
	 * @param objectToUpdate must not be {@literal null}.
	 * @return the updated object.
	 */
	<T> T update(Object id, T objectToUpdate);

	/**
	 * Remove all elements of type. Respects {@link KeySpace} if present and therefore removes all elements that can be
	 * assigned to requested type.
	 *
	 * @param type must not be {@literal null}.
	 */
	void delete(Class<?> type);

	/**
	 * @param objectToDelete must not be {@literal null}.
	 * @return
	 */
	<T> @Nullable T delete(T objectToDelete);

	/**
	 * Delete item of type with given id.
	 *
	 * @param id must not be {@literal null}.
	 * @param type must not be {@literal null}.
	 * @return the deleted item or {@literal null} if no match found.
	 */
	<T> @Nullable T delete(Object id, Class<T> type);

	/**
	 * Total number of elements with given type available. Respects {@link KeySpace} if present and therefore counts all
	 * elements that can be assigned to requested type.
	 *
	 * @param type must not be {@literal null}.
	 * @return
	 */
	long count(Class<?> type);

	/**
	 * Total number of elements matching given query. Respects {@link KeySpace} if present and therefore counts all
	 * elements that can be assigned to requested type.
	 *
	 * @param query
	 * @param type
	 * @return
	 */
	long count(KeyValueQuery<?> query, Class<?> type);

	/**
	 * Determine whether result of given {@link KeyValueQuery} contains at least one element.
	 *
	 * @param query
	 * @param type
	 * @return
	 * @since 2.7
	 */
	boolean exists(KeyValueQuery<?> query, Class<?> type);

	/**
	 * @return mapping context in use.
	 */
	MappingContext<?, ?> getMappingContext();

	/**
	 * @return {@link KeyValueAdapter} in use.
	 * @since 3.2.4
	 */
	KeyValueAdapter getKeyValueAdapter();
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslator.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.NoSuchElementException;

import org.jspecify.annotations.Nullable;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.util.Assert;

/**
 * Simple {@link PersistenceExceptionTranslator} implementation for key/value stores that converts the given runtime
 * exception to an appropriate exception from the {@code org.springframework.dao} hierarchy.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 */
public class KeyValuePersistenceExceptionTranslator implements PersistenceExceptionTranslator {

	@Override
	@SuppressWarnings("NullAway")
	public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException exception) {

		Assert.notNull(exception, "Exception must not be null");

		if (exception instanceof DataAccessException) {
			return (DataAccessException) exception;
		}

		if (exception instanceof NoSuchElementException || exception instanceof IndexOutOfBoundsException
				|| exception instanceof IllegalStateException) {
			return new DataRetrievalFailureException(exception.getMessage(), exception);
		}

		if (exception.getClass().getName().startsWith("java")) {
			return new UncategorizedKeyValueException(exception.getMessage(), exception);
		}

		return null;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.jspecify.annotations.Nullable;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.domain.Sort;
import org.springframework.data.keyvalue.core.event.KeyValueEvent;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;

/**
 * Basic implementation of {@link KeyValueOperations}.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 * @author Thomas Darimont
 * @author Mark Paluch
 * @author Mert Zeybekler
 * @author Adeyemi Abass
 */
public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPublisherAware {

	private static final PersistenceExceptionTranslator DEFAULT_PERSISTENCE_EXCEPTION_TRANSLATOR = new KeyValuePersistenceExceptionTranslator();

	private final KeyValueAdapter adapter;
	private final MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext;
	private final IdentifierGenerator identifierGenerator;

	private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_PERSISTENCE_EXCEPTION_TRANSLATOR;
	private @Nullable ApplicationEventPublisher eventPublisher;
	private boolean publishEvents = true;
	private @SuppressWarnings("rawtypes") Set<Class<? extends KeyValueEvent>> eventTypesToPublish = Collections
			.emptySet();

	/**
	 * Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} with a default
	 * {@link KeyValueMappingContext}.
	 *
	 * @param adapter must not be {@literal null}.
	 */
	public KeyValueTemplate(KeyValueAdapter adapter) {
		this(adapter, new KeyValueMappingContext<>());
	}

	/**
	 * Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link MappingContext}.
	 *
	 * @param adapter must not be {@literal null}.
	 * @param mappingContext must not be {@literal null}.
	 */
	public KeyValueTemplate(KeyValueAdapter adapter,
			MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext) {
		this(adapter, mappingContext, DefaultIdentifierGenerator.INSTANCE);
	}

	/**
	 * Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link MappingContext}.
	 *
	 * @param adapter must not be {@literal null}.
	 * @param mappingContext must not be {@literal null}.
	 * @param identifierGenerator must not be {@literal null}.
	 * @since 2.4
	 */
	public KeyValueTemplate(KeyValueAdapter adapter,
			MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext,
			IdentifierGenerator identifierGenerator) {

		Assert.notNull(adapter, "Adapter must not be null");
		Assert.notNull(mappingContext, "MappingContext must not be null");
		Assert.notNull(identifierGenerator, "IdentifierGenerator must not be null");

		this.adapter = adapter;
		this.mappingContext = mappingContext;
		this.identifierGenerator = identifierGenerator;
	}

	/**
	 * Set the {@link PersistenceExceptionTranslator} used for converting {@link RuntimeException}.
	 *
	 * @param exceptionTranslator must not be {@literal null}.
	 */
	public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {

		Assert.notNull(exceptionTranslator, "ExceptionTranslator must not be null");
		this.exceptionTranslator = exceptionTranslator;
	}

	/**
	 * Define the event types to publish via {@link ApplicationEventPublisher}.
	 *
	 * @param eventTypesToPublish use {@literal null} or {@link Collections#emptySet()} to stop publishing.
	 */
	@SuppressWarnings("rawtypes")
	public void setEventTypesToPublish(Set<Class<? extends KeyValueEvent>> eventTypesToPublish) {

		if (CollectionUtils.isEmpty(eventTypesToPublish)) {
			this.publishEvents = false;
		} else {
			this.publishEvents = true;
			this.eventTypesToPublish = Collections.unmodifiableSet(eventTypesToPublish);
		}
	}

	@Override
	public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
		this.eventPublisher = applicationEventPublisher;
	}

	@Override
	public <T> T insert(T objectToInsert) {

		KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToInsert);

		GeneratingIdAccessor generatingIdAccessor = new GeneratingIdAccessor(entity.getPropertyAccessor(objectToInsert),
				entity.getRequiredIdProperty(), identifierGenerator);
		Object id = generatingIdAccessor.getOrGenerateIdentifier();

		return insert(id, objectToInsert);
	}

	@Override
	public <T> T insert(Object id, T objectToInsert) {

		Assert.notNull(id, "Id for object to be inserted must not be null");
		Assert.notNull(objectToInsert, "Object to be inserted must not be null");

		String keyspace = resolveKeySpace(objectToInsert.getClass());

		potentiallyPublishEvent(KeyValueEvent.beforeInsert(id, keyspace, objectToInsert.getClass(), objectToInsert));

		execute((KeyValueCallback<Void>) adapter -> {

			if (adapter.contains(id, keyspace)) {
				throw new DuplicateKeyException(
						String.format("Cannot insert existing object with id %s; Please use update", id));
			}

			adapter.put(id, objectToInsert, keyspace);
			return null;
		});

		potentiallyPublishEvent(KeyValueEvent.afterInsert(id, keyspace, objectToInsert.getClass(), objectToInsert));

		return objectToInsert;
	}

	@Override
	public <T> T update(T objectToUpdate) {

		KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToUpdate);

		if (!entity.hasIdProperty()) {
			throw new InvalidDataAccessApiUsageException(
					String.format("Cannot determine id for type %s", ClassUtils.getUserClass(objectToUpdate)));
		}

		return update(entity.getIdentifierAccessor(objectToUpdate).getRequiredIdentifier(), objectToUpdate);
	}

	@Override
	public <T> T update(Object id, T objectToUpdate) {

		Assert.notNull(id, "Id for object to be inserted must not be null");
		Assert.notNull(objectToUpdate, "Object to be updated must not be null");

		String keyspace = resolveKeySpace(objectToUpdate.getClass());

		potentiallyPublishEvent(KeyValueEvent.beforeUpdate(id, keyspace, objectToUpdate.getClass(), objectToUpdate));

		Object existing = execute(adapter -> adapter.put(id, objectToUpdate, keyspace));

		potentiallyPublishEvent(
				KeyValueEvent.afterUpdate(id, keyspace, objectToUpdate.getClass(), objectToUpdate, existing));

		return objectToUpdate;
	}

	@Override
	public <T> Iterable<T> findAll(Class<T> type) {

		Assert.notNull(type, "Type to fetch must not be null");

		return executeRequired(adapter -> {

			String keyspace = resolveKeySpace(type);
			Iterable<?> values = adapter.getAllOf(keyspace, type);

			ArrayList<T> filtered = new ArrayList<>();
			for (Object candidate : values) {
				if (typeCheck(type, candidate)) {
					filtered.add(type.cast(candidate));
				}
			}

			return filtered;
		});
	}

	@Override
	public <T> Optional<T> findById(Object id, Class<T> type) {

		Assert.notNull(id, "Id for object to be found must not be null");
		Assert.notNull(type, "Type to fetch must not be null");

		String keyspace = resolveKeySpace(type);

		potentiallyPublishEvent(KeyValueEvent.beforeGet(id, keyspace, type));

		T result = execute(adapter -> {

			Object value = adapter.get(id, keyspace, type);

			if (value == null || typeCheck(type, value)) {
				return type.cast(value);
			}

			return null;
		});

		potentiallyPublishEvent(KeyValueEvent.afterGet(id, keyspace, type, result));

		return Optional.ofNullable(result);
	}

	@Override
	public void delete(Class<?> type) {

		Assert.notNull(type, "Type to delete must not be null");

		String keyspace = resolveKeySpace(type);
		potentiallyPublishEvent(KeyValueEvent.beforeDropKeySpace(keyspace, type));

		execute((KeyValueCallback<Void>) adapter -> {

			adapter.deleteAllOf(keyspace);
			return null;
		});

		potentiallyPublishEvent(KeyValueEvent.afterDropKeySpace(keyspace, type));
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> @Nullable T delete(T objectToDelete) {

		Class<T> type = (Class<T>) ClassUtils.getUserClass(objectToDelete);
		KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToDelete);

		return delete(entity.getIdentifierAccessor(objectToDelete).getRequiredIdentifier(), type);
	}

	@Override
	public <T> @Nullable T delete(Object id, Class<T> type) {

		Assert.notNull(id, "Id for object to be deleted must not be null");
		Assert.notNull(type, "Type to delete must not be null");

		String keyspace = resolveKeySpace(type);

		potentiallyPublishEvent(KeyValueEvent.beforeDelete(id, keyspace, type));

		T result = execute(adapter -> adapter.delete(id, keyspace, type));

		potentiallyPublishEvent(KeyValueEvent.afterDelete(id, keyspace, type, result));

		return result;
	}

	@Override
	public long count(Class<?> type) {

		Assert.notNull(type, "Type for count must not be null");
		String keyspace = resolveKeySpace(type);
		return adapter.count(keyspace);
	}

	@Override
	public <T> @Nullable T execute(KeyValueCallback<T> action) {

		Assert.notNull(action, "KeyValueCallback must not be null");

		try {
			return action.doInKeyValue(this.adapter);
		} catch (RuntimeException e) {
			throw resolveExceptionIfPossible(e);
		}
	}

	/**
	 * Execute {@link KeyValueCallback} and require a non-{@literal null} return value.
	 *
	 * @param action
	 * @param <T>
	 * @return
	 */
	protected <T> T executeRequired(KeyValueCallback<T> action) {

		T result = execute(action);

		if (result != null) {
			return result;
		}

		throw new IllegalStateException(String.format("KeyValueCallback %s returned null value", action));
	}

	@Override
	public <T> Iterable<T> find(KeyValueQuery<?> query, Class<T> type) {

		return executeRequired((KeyValueCallback<Iterable<T>>) adapter -> {

			Iterable<?> result = adapter.find(query, resolveKeySpace(type), type);

			List<T> filtered = new ArrayList<>();

			for (Object candidate : result) {
				if (typeCheck(type, candidate)) {
					filtered.add(type.cast(candidate));
				}
			}

			return filtered;
		});
	}

	@SuppressWarnings("rawtypes")
	@Override
	public <T> Iterable<T> findAll(Sort sort, Class<T> type) {
		return find(new KeyValueQuery(sort), type);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public <T> Iterable<T> findInRange(long offset, int rows, Class<T> type) {
		return find(new KeyValueQuery().skip(offset).limit(rows), type);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public <T> Iterable<T> findInRange(long offset, int rows, Sort sort, Class<T> type) {
		return find(new KeyValueQuery(sort).skip(offset).limit(rows), type);
	}

	@Override
	public long count(KeyValueQuery<?> query, Class<?> type) {
		return executeRequired(adapter -> adapter.count(query, resolveKeySpace(type)));
	}

	@Override
	public boolean exists(KeyValueQuery<?> query, Class<?> type) {
		return executeRequired(adapter -> adapter.exists(query, resolveKeySpace(type)));
	}

	@Override
	public MappingContext<?, ?> getMappingContext() {
		return this.mappingContext;
	}

	@Override
	public KeyValueAdapter getKeyValueAdapter() {
		return adapter;
	}

	@Override
	public void destroy() throws Exception {
		this.adapter.clear();
	}

	private KeyValuePersistentEntity<?, ?> getKeyValuePersistentEntity(Object objectToInsert) {
		return this.mappingContext.getRequiredPersistentEntity(ClassUtils.getUserClass(objectToInsert));
	}


	private  String resolveKeySpace(Class<?> type) {

		String keyspace = this.mappingContext.getRequiredPersistentEntity(type).getKeySpace();
		Assert.notNull(keyspace, "Keyspace must not be null");
		return keyspace;
	}

	private RuntimeException resolveExceptionIfPossible(RuntimeException e) {

		DataAccessException translatedException = exceptionTranslator.translateExceptionIfPossible(e);
		return translatedException != null ? translatedException : e;
	}

	@SuppressWarnings("rawtypes")
	private void potentiallyPublishEvent(KeyValueEvent event) {

		if (eventPublisher == null) {
			return;
		}

		if (publishEvents && (eventTypesToPublish.isEmpty() || eventTypesToPublish.contains(event.getClass()))) {
			eventPublisher.publishEvent(event);
		}
	}

	private static boolean typeCheck(Class<?> requiredType, @Nullable Object candidate) {
		return candidate == null || ClassUtils.isAssignable(requiredType, candidate.getClass());
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/PathSortAccessor.java
================================================
/*
 * Copyright 2024-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Comparator;
import java.util.Optional;

import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.NullHandling;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;

/**
 * @author Christoph Strobl
 * @since 3.1.10
 */
public class PathSortAccessor implements SortAccessor<Comparator<?>> {

	@Override
	public @Nullable Comparator<?> resolve(KeyValueQuery<?> query) {

		if (query.getSort().isUnsorted()) {
			return null;
		}

		Optional<Comparator<?>> comparator = Optional.empty();
		for (Order order : query.getSort()) {

			PropertyPathComparator<Object> pathSort = new PropertyPathComparator<>(order.getProperty());

			if (Direction.DESC.equals(order.getDirection())) {

				pathSort.desc();

				if (!NullHandling.NATIVE.equals(order.getNullHandling())) {
					pathSort = NullHandling.NULLS_FIRST.equals(order.getNullHandling()) ? pathSort.nullsFirst()
							: pathSort.nullsLast();
				}
			}

			if (!comparator.isPresent()) {
				comparator = Optional.of(pathSort);
			} else {

				PropertyPathComparator<Object> pathSortToUse = pathSort;
				comparator = comparator.map(it -> it.thenComparing(pathSortToUse));
			}
		}

		return comparator.orElseThrow(
				() -> new IllegalStateException("No sort definitions have been added to this CompoundComparator to compare"));

	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/PredicateQueryEngine.java
================================================
/*
 * Copyright 2024-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.jspecify.annotations.Nullable;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.lang.Contract;

/**
 * {@link QueryEngine} implementation specific for executing {@link Predicate} based {@link KeyValueQuery} against
 * {@link KeyValueAdapter}.
 *
 * @author Christoph Strobl
 * @since 3.3
 */
public class PredicateQueryEngine extends QueryEngine<KeyValueAdapter, Predicate<?>, Comparator<?>> {

	public static final PredicateQueryEngine INSTANCE = new PredicateQueryEngine();

	/**
	 * Creates a new {@link PredicateQueryEngine}.
	 */
	public PredicateQueryEngine() {
		this(new PathSortAccessor());
	}

	/**
	 * Creates a new query engine using provided {@link SortAccessor accessor} for sorting results.
	 */
	public PredicateQueryEngine(SortAccessor<Comparator<?>> sortAccessor) {
		super(new CriteriaAccessor<>() {

			@Override
			public @Nullable Predicate<?> resolve(KeyValueQuery<?> query) {
				return (Predicate<?>) query.getCriteria();
			}
		}, sortAccessor);
	}

	@Override
	public Collection<?> execute(@Nullable Predicate<?> criteria, @Nullable Comparator<?> sort, long offset, int rows,
			String keyspace) {
		return sortAndFilterMatchingRange(getRequiredAdapter().getAllOf(keyspace), criteria, sort, offset, rows);
	}

	@Override
	public long count(@Nullable Predicate<?> criteria, String keyspace) {
		return filterMatchingRange(IterableConverter.toList(getRequiredAdapter().getAllOf(keyspace)), criteria, -1, -1)
				.size();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private List<?> sortAndFilterMatchingRange(Iterable<?> source, @Nullable Predicate<?> criteria,
			@Nullable Comparator sort, long offset, int rows) {

		List<?> tmp = IterableConverter.toList(source);
		if (sort != null) {
			tmp.sort(sort);
		}

		return filterMatchingRange(tmp, criteria, offset, rows);
	}

	@Contract("!null, _, _, _ -> !null")
	private static <S> List<S> filterMatchingRange(List<S> source, @Nullable Predicate<?> criteria, long offset, int rows) {

		Stream<S> stream = source.stream();

		if (criteria != null) {
			stream = stream.filter((Predicate<? super S>) criteria);
		}
		if (offset > 0) {
			stream = stream.skip(offset);
		}
		if (rows > 0) {
			stream = stream.limit(rows);
		}

		return stream.collect(Collectors.toList());
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/PropertyPathComparator.java
================================================
/*
 * Copyright 2024-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

import org.jspecify.annotations.Nullable;
import org.springframework.data.core.PropertyPath;
import org.springframework.lang.Contract;

/**
 * {@link Comparator} implementation to compare objects based on a {@link PropertyPath}. This comparator obtains the
 * value at {@link PropertyPath} from the {@link #compare(Object, Object) given comparison objects} and then performs
 * the comparison.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 * @since 3.1.10
 */
public class PropertyPathComparator<T> implements Comparator<T> {

	private static final Comparator<?> NULLS_FIRST = Comparator.nullsFirst(Comparator.naturalOrder());
	private static final Comparator<?> NULLS_LAST = Comparator.nullsLast(Comparator.naturalOrder());

	private final String path;

	private boolean asc = true;
	private boolean nullsFirst = true;

	private final Map<Class<?>, PropertyPath> pathCache = new HashMap<>(2);

	public PropertyPathComparator(String path) {
		this.path = path;
	}

	@Override
	public int compare(@Nullable T o1, @Nullable T o2) {

		if (o1 == null && o2 == null) {
			return 0;
		}
		if (o1 == null) {
			return nullsFirst ? 1 : -1;
		}
		if (o2 == null) {
			return nullsFirst ? 1 : -1;
		}

		PropertyPath propertyPath = pathCache.computeIfAbsent(o1.getClass(), it -> PropertyPath.from(path, it));
		Object value1 = getCompareValue(o1, propertyPath);
		Object value2 = getCompareValue(o2, propertyPath);

		return getComparator().compare(value1, value2) * (asc ? 1 : -1);
	}

	protected <S> @Nullable Object getCompareValue(S object, PropertyPath propertyPath) {
		return new SimplePropertyPathAccessor<>(object).getValue(propertyPath);
	}

	@SuppressWarnings("unchecked")
	private Comparator<@Nullable Object> getComparator() {
		return (Comparator<Object>) (nullsFirst ? NULLS_FIRST : NULLS_LAST);
	}

	/**
	 * Sort {@literal ascending}.
	 *
	 * @return
	 */
	@Contract("-> this")
	public PropertyPathComparator<@Nullable T> asc() {
		this.asc = true;
		return this;
	}

	/**
	 * Sort {@literal descending}.
	 *
	 * @return
	 */
	@Contract("-> this")
	public PropertyPathComparator<@Nullable T> desc() {
		this.asc = false;
		return this;
	}

	/**
	 * Sort {@literal null} values first.
	 *
	 * @return
	 */
	@Contract("-> this")
	public PropertyPathComparator<@Nullable T> nullsFirst() {
		this.nullsFirst = true;
		return this;
	}

	/**
	 * Sort {@literal null} values last.
	 *
	 * @return
	 */
	@Contract("-> this")
	public PropertyPathComparator<@Nullable T> nullsLast() {
		this.nullsFirst = false;
		return this;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/QueryEngine.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Collection;
import java.util.Optional;

import org.jspecify.annotations.Nullable;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;

/**
 * Base implementation for accessing and executing {@link KeyValueQuery} against a {@link KeyValueAdapter}.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 * @param <ADAPTER>
 * @param <CRITERIA>
 * @param <SORT>
 */
public abstract class QueryEngine<ADAPTER extends KeyValueAdapter, CRITERIA, SORT> {

	private final Optional<CriteriaAccessor<CRITERIA>> criteriaAccessor;
	private final Optional<SortAccessor<SORT>> sortAccessor;

	private @Nullable ADAPTER adapter;

	public QueryEngine(@Nullable CriteriaAccessor<CRITERIA> criteriaAccessor, @Nullable SortAccessor<SORT> sortAccessor) {

		this.criteriaAccessor = Optional.ofNullable(criteriaAccessor);
		this.sortAccessor = Optional.ofNullable(sortAccessor);
	}

	/**
	 * Extract query attributes and delegate to concrete execution.
	 *
	 * @param query
	 * @param keyspace
	 * @return
	 */
	public Collection<?> execute(KeyValueQuery<?> query, String keyspace) {

		CRITERIA criteria = this.criteriaAccessor.map(it -> it.resolve(query)).orElse(null);
		SORT sort = this.sortAccessor.map(it -> it.resolve(query)).orElse(null);

		return execute(criteria, sort, query.getOffset(), query.getRows(), keyspace);
	}

	/**
	 * Extract query attributes and delegate to concrete execution.
	 *
	 * @param query
	 * @param keyspace
	 * @return
	 */
	public <T> Collection<T> execute(KeyValueQuery<?> query, String keyspace, Class<T> type) {

		CRITERIA criteria = this.criteriaAccessor.map(it -> it.resolve(query)).orElse(null);
		SORT sort = this.sortAccessor.map(it -> it.resolve(query)).orElse(null);

		return execute(criteria, sort, query.getOffset(), query.getRows(), keyspace, type);
	}

	/**
	 * Extract query attributes and delegate to concrete execution.
	 *
	 * @param query
	 * @param keyspace
	 * @return
	 */
	public long count(KeyValueQuery<?> query, String keyspace) {

		CRITERIA criteria = this.criteriaAccessor.map(it -> it.resolve(query)).orElse(null);
		return count(criteria, keyspace);
	}

	/**
	 * @param criteria
	 * @param sort
	 * @param offset
	 * @param rows
	 * @param keyspace
	 * @return
	 */
	public abstract Collection<?> execute(@Nullable CRITERIA criteria, @Nullable SORT sort, long offset, int rows,
			String keyspace);

	/**
	 * @param criteria
	 * @param sort
	 * @param offset
	 * @param rows
	 * @param keyspace
	 * @param type
	 * @return
	 * @since 1.1
	 */
	@SuppressWarnings("unchecked")
	public <T> Collection<T> execute(@Nullable CRITERIA criteria, @Nullable SORT sort, long offset, int rows,
			String keyspace, Class<T> type) {
		return (Collection<T>) execute(criteria, sort, offset, rows, keyspace);
	}

	/**
	 * @param criteria
	 * @param keyspace
	 * @return
	 */
	public abstract long count(@Nullable CRITERIA criteria, String keyspace);

	/**
	 * Get the {@link KeyValueAdapter} used.
	 *
	 * @return
	 */
	protected @Nullable ADAPTER getAdapter() {
		return this.adapter;
	}

	/**
	 * Get the required {@link KeyValueAdapter} used or throw {@link IllegalStateException} if the adapter is not set.
	 *
	 * @return the required {@link KeyValueAdapter}.
	 * @throws IllegalStateException if the adapter is not set.
	 */
	protected ADAPTER getRequiredAdapter() {

		ADAPTER adapter = getAdapter();

		if (adapter != null) {
			return adapter;
		}

		throw new IllegalStateException("Required KeyValueAdapter is not set");
	}

	/**
	 * @param adapter
	 */
	@SuppressWarnings("unchecked")
	public void registerAdapter(KeyValueAdapter adapter) {

		if (this.adapter == null) {
			this.adapter = (ADAPTER) adapter;
		} else {
			throw new IllegalArgumentException("Cannot register more than one adapter for this QueryEngine");
		}
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/QueryEngineFactory.java
================================================
/*
 * Copyright 2024-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

/**
 * Interface for {@code QueryEngineFactory} implementations that provide a {@link QueryEngine} object as part of the
 * configuration.
 * <p>
 * The factory is used during configuration to supply the query engine to be used. When configured, a
 * {@code QueryEngineFactory} can be instantiated by accepting a {@link SortAccessor} in its constructor. Otherwise,
 * implementations are expected to declare a no-args constructor.
 *
 * @author Mark Paluch
 * @since 3.3.1
 */
public interface QueryEngineFactory {

	/**
	 * Factory method for creating a {@link QueryEngine}.
	 *
	 * @return the query engine.
	 */
	QueryEngine<?, ?, ?> create();
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/SimplePropertyPathAccessor.java
================================================
/*
 * Copyright 2024-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeanWrapper;
import org.springframework.data.core.PropertyPath;
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;

/**
 * @author Christoph Strobl
 * @since 3.1.10
 */
public class SimplePropertyPathAccessor<T> {

	private final Object root;

	public SimplePropertyPathAccessor(Object source) {
		this.root = source;
	}

	public @Nullable Object getValue(PropertyPath path) {

		Object currentValue = root;
		for (PropertyPath current : path) {
			currentValue = wrap(currentValue).getPropertyValue(current.getSegment());
			if (currentValue == null) {
				break;
			}
		}
		return currentValue;
	}

	BeanWrapper wrap(Object o) {
		return new DirectFieldAccessFallbackBeanWrapper(o);
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/SortAccessor.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Sort;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;

/**
 * Resolves the {@link Sort} object from given {@link KeyValueQuery} and potentially converts it into a store specific
 * representation that can be used by the {@link QueryEngine} implementation.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 * @param <T>
 */
public interface SortAccessor<T> {

	/**
	 * Reads {@link KeyValueQuery#getSort()} of given {@link KeyValueQuery} and applies required transformation to match
	 * the desired type.
	 *
	 * @param query must not be {@literal null}.
	 * @return {@literal null} in case {@link Sort} has not been defined on {@link KeyValueQuery}.
	 */
	@Nullable
	T resolve(KeyValueQuery<?> query);
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/SpelCriteria.java
================================================
/*
 * Copyright 2016-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.util.Assert;

/**
 * {@link SpelCriteria} allows to pass on a {@link SpelExpression} and {@link EvaluationContext} to the actual query
 * processor. This decouples the {@link SpelExpression} from the context it is used in.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 */
public class SpelCriteria {

	private final SpelExpression expression;
	private final EvaluationContext context;

	/**
	 * Creates a new {@link SpelCriteria} for the given {@link SpelExpression}.
	 *
	 * @param expression must not be {@literal null}.
	 */
	public SpelCriteria(SpelExpression expression) {
		this(expression, SimpleEvaluationContext.forReadOnlyDataBinding().withInstanceMethods().build());
	}

	/**
	 * Creates new {@link SpelCriteria}.
	 *
	 * @param expression must not be {@literal null}.
	 * @param context must not be {@literal null}.
	 */
	public SpelCriteria(SpelExpression expression, EvaluationContext context) {

		Assert.notNull(expression, "SpEL expression must not be null");
		Assert.notNull(context, "EvaluationContext must not be null");

		this.expression = expression;
		this.context = context;
	}

	/**
	 * @return will never be {@literal null}.
	 */
	public EvaluationContext getContext() {
		return context;
	}

	/**
	 * @return will never be {@literal null}.
	 */
	public SpelExpression getExpression() {
		return expression;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/SpelCriteriaAccessor.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.jspecify.annotations.Nullable;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.Assert;

/**
 * {@link CriteriaAccessor} implementation capable of {@link SpelExpression}s.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 */
class SpelCriteriaAccessor implements CriteriaAccessor<SpelCriteria> {

	private final SpelExpressionParser parser;

	/**
	 * Creates a new {@link SpelCriteriaAccessor} using the given {@link SpelExpressionParser}.
	 *
	 * @param parser must not be {@literal null}.
	 */
	public SpelCriteriaAccessor(SpelExpressionParser parser) {

		Assert.notNull(parser, "SpelExpressionParser must not be null");

		this.parser = parser;
	}

	@Override
	public @Nullable SpelCriteria resolve(KeyValueQuery<?> query) {

		if (query.getCriteria() == null) {
			return null;
		}

		if (query.getCriteria() instanceof SpelExpression) {
			return new SpelCriteria((SpelExpression) query.getCriteria());
		}

		if (query.getCriteria() instanceof String) {
			return new SpelCriteria(parser.parseRaw((String) query.getCriteria()));
		}

		if (query.getCriteria() instanceof SpelCriteria) {
			return (SpelCriteria) query.getCriteria();
		}

		throw new IllegalArgumentException("Cannot create SpelCriteria for " + query.getCriteria());
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/SpelPropertyComparator.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Comparator;

import org.jspecify.annotations.Nullable;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;

/**
 * {@link Comparator} implementation using {@link SpelExpression}.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 * @author Mark Paluch
 * @param <T>
 */
public class SpelPropertyComparator<T> implements Comparator<T> {

	private static final Comparator<?> NULLS_FIRST = Comparator.nullsFirst(Comparator.naturalOrder());
	private static final Comparator<?> NULLS_LAST = Comparator.nullsLast(Comparator.naturalOrder());

	private final String path;
	private final SpelExpressionParser parser;

	private boolean asc = true;
	private boolean nullsFirst = true;
	private @Nullable SpelExpression expression;

	/**
	 * Create new {@link SpelPropertyComparator} for the given property path an {@link SpelExpressionParser}.
	 *
	 * @param path must not be {@literal null} or empty.
	 * @param parser must not be {@literal null}.
	 */
	public SpelPropertyComparator(String path, SpelExpressionParser parser) {

		Assert.hasText(path, "Path must not be null or empty");
		Assert.notNull(parser, "SpelExpressionParser must not be null");

		this.path = path;
		this.parser = parser;
	}

	/**
	 * Sort {@literal ascending}.
	 *
	 * @return
	 */
	@Contract("-> this")
	public SpelPropertyComparator<@Nullable T> asc() {
		this.asc = true;
		return this;
	}

	/**
	 * Sort {@literal descending}.
	 *
	 * @return
	 */
	@Contract("-> this")
	public SpelPropertyComparator<@Nullable T> desc() {
		this.asc = false;
		return this;
	}

	/**
	 * Sort {@literal null} values first.
	 *
	 * @return
	 */
	@Contract("-> this")
	public SpelPropertyComparator<@Nullable T> nullsFirst() {
		this.nullsFirst = true;
		return this;
	}

	/**
	 * Sort {@literal null} values last.
	 *
	 * @return
	 */
	@Contract("-> this")
	public SpelPropertyComparator<@Nullable T> nullsLast() {
		this.nullsFirst = false;
		return this;
	}

	/**
	 * Parse values to {@link SpelExpression}
	 *
	 * @return
	 */
	protected SpelExpression getExpression() {

		if (this.expression == null) {
			this.expression = parser.parseRaw(buildExpressionForPath());
		}

		return this.expression;
	}

	/**
	 * Create the expression raw value.
	 *
	 * @return
	 */
	protected String buildExpressionForPath() {

		return String.format("#comparator.compare(#arg1?.%s,#arg2?.%s)", path.replace(".", "?."),
				path.replace(".", "?."));
	}

	@Override
	public int compare(@Nullable T arg1, @Nullable T arg2) {

		SpelExpression expressionToUse = getExpression();

		SimpleEvaluationContext ctx = SimpleEvaluationContext.forReadOnlyDataBinding().withInstanceMethods().build();
		ctx.setVariable("comparator", nullsFirst ? NULLS_FIRST : NULLS_LAST);
		ctx.setVariable("arg1", arg1);
		ctx.setVariable("arg2", arg2);

		expressionToUse.setEvaluationContext(ctx);

		Integer value = expressionToUse.getValue(Integer.class);
		return (value != null ? value : 0) * (asc ? 1 : -1);
	}

	/**
	 * Get dot path to property.
	 *
	 * @return
	 */
	public String getPath() {
		return path;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.jspecify.annotations.Nullable;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;

/**
 * {@link QueryEngine} implementation specific for executing {@link SpelExpression} based {@link KeyValueQuery} against
 * {@link KeyValueAdapter}.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 * @author Mark Paluch
 */
public class SpelQueryEngine extends QueryEngine<KeyValueAdapter, SpelCriteria, Comparator<?>> {

	private static final SpelExpressionParser PARSER = new SpelExpressionParser();

	/**
	 * Creates a new {@link SpelQueryEngine}.
	 */
	public SpelQueryEngine() {
		this(new SpelSortAccessor(PARSER));
	}

	/**
	 * Creates a new query engine using provided {@link SortAccessor accessor} for sorting results.
	 *
	 * @since 3.1.10
	 */
	public SpelQueryEngine(SortAccessor<Comparator<?>> sortAccessor) {
		super(new SpelCriteriaAccessor(PARSER), sortAccessor);
	}

	@Override
	public Collection<?> execute(@Nullable SpelCriteria criteria, @Nullable Comparator<?> sort, long offset, int rows,
			String keyspace) {
		return sortAndFilterMatchingRange(getRequiredAdapter().getAllOf(keyspace), criteria, sort, offset, rows);
	}

	@Override
	public long count(@Nullable SpelCriteria criteria, String keyspace) {
		return filterMatchingRange(IterableConverter.toList(getRequiredAdapter().getAllOf(keyspace)), criteria, -1, -1)
				.size();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private List<?> sortAndFilterMatchingRange(Iterable<?> source, @Nullable SpelCriteria criteria,
			@Nullable Comparator sort, long offset, int rows) {

		List<?> tmp = IterableConverter.toList(source);
		if (sort != null) {
			tmp.sort(sort);
		}

		return filterMatchingRange(tmp, criteria, offset, rows);
	}

	private static <S> List<S> filterMatchingRange(List<S> source, @Nullable SpelCriteria criteria, long offset,
			int rows) {

		Stream<S> stream = source.stream();

		if (criteria != null) {
			stream = stream.filter(it -> evaluateExpression(criteria, it));
		}
		if (offset > 0) {
			stream = stream.skip(offset);
		}
		if (rows > 0) {
			stream = stream.limit(rows);
		}

		return stream.collect(Collectors.toList());
	}

	@SuppressWarnings("NullAway")
	private static boolean evaluateExpression(SpelCriteria criteria, Object candidate) {

		try {
			return criteria.getExpression().getValue(criteria.getContext(), candidate, Boolean.class);
		} catch (SpelEvaluationException e) {
			criteria.getContext().setVariable("it", candidate);
			return criteria.getExpression().getValue(criteria.getContext()) == null ? false
					: criteria.getExpression().getValue(criteria.getContext(), Boolean.class);
		}
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/SpelSortAccessor.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import java.util.Comparator;
import java.util.Optional;

import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.NullHandling;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.Assert;

/**
 * {@link SortAccessor} implementation capable of creating {@link SpelPropertyComparator}.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 * @author Mark Paluch
 */
public class SpelSortAccessor implements SortAccessor<Comparator<?>> {

	private final SpelExpressionParser parser;

	/**
	 * Creates a new {@link SpelSortAccessor} given {@link SpelExpressionParser}.
	 *
	 * @param parser must not be {@literal null}.
	 */
	public SpelSortAccessor(SpelExpressionParser parser) {

		Assert.notNull(parser, "SpelExpressionParser must not be null");
		this.parser = parser;
	}

	@Override
	public @Nullable Comparator<?> resolve(KeyValueQuery<?> query) {

		if (query.getSort().isUnsorted()) {
			return null;
		}

		Optional<Comparator<?>> comparator = Optional.empty();
		for (Order order : query.getSort()) {

			SpelPropertyComparator<Object> spelSort = new SpelPropertyComparator<>(order.getProperty(), parser);

			if (Direction.DESC.equals(order.getDirection())) {

				spelSort.desc();

				if (!NullHandling.NATIVE.equals(order.getNullHandling())) {
					spelSort = NullHandling.NULLS_FIRST.equals(order.getNullHandling()) ? spelSort.nullsFirst()
							: spelSort.nullsLast();
				}
			}

			if (!comparator.isPresent()) {
				comparator = Optional.of(spelSort);
			} else {

				SpelPropertyComparator<Object> spelSortToUse = spelSort;
				comparator = comparator.map(it -> it.thenComparing(spelSortToUse));
			}
		}

		return comparator.orElseThrow(
				() -> new IllegalStateException("No sort definitions have been added to this CompoundComparator to compare"));
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/UncategorizedKeyValueException.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core;

import org.springframework.dao.UncategorizedDataAccessException;

/**
 * Normal superclass when we can't distinguish anything more specific than "something went wrong with the underlying
 * resource".
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 */
public class UncategorizedKeyValueException extends UncategorizedDataAccessException {

	private static final long serialVersionUID = -8087116071859122297L;

	/**
	 * Creates a new {@link UncategorizedKeyValueException}.
	 *
	 * @param msg the detail message.
	 * @param cause the root cause (usually from using a underlying data access API).
	 */
	public UncategorizedKeyValueException(String msg, Throwable cause) {
		super(msg, cause);
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/event/KeyValueEvent.java
================================================
/*
 * Copyright 2015-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.event;

import org.jspecify.annotations.Nullable;
import org.springframework.context.ApplicationEvent;

/**
 * {@link KeyValueEvent} gets published for operations executed by eg.
 * {@link org.springframework.data.keyvalue.core.KeyValueTemplate}.
 *
 * Use the {@link KeyValueEvent.KeyBasedEvent#getType()} to determine which event has been emitted.
 *
 * @author Christoph Strobl
 * @author Thomas Darimont
 * @author Mark Paluch
 * @param <T>
 */
public class KeyValueEvent<T> extends ApplicationEvent {

	private static final long serialVersionUID = -7128527253428193044L;

	private final String keyspace;

	protected KeyValueEvent(Object source, String keyspace) {

		super(source);
		this.keyspace = keyspace;
	}

	/**
	 * @return affected keyspace. Never {@literal null}.
	 */
	public String getKeyspace() {
		return keyspace;
	}

	@Override
	public String toString() {
		return "KeyValueEvent [keyspace=" + keyspace + ", source=" + getSource() + "]";
	}

	/**
	 * Create new {@link BeforeGetEvent}.
	 *
	 * @param id
	 * @param keyspace
	 * @param type
	 * @return
	 */
	public static <T> BeforeGetEvent<T> beforeGet(Object id, String keyspace, Class<T> type) {
		return new BeforeGetEvent<>(id, keyspace, type);
	}

	/**
	 * Create new {@link AfterGetEvent}.
	 *
	 * @param id
	 * @param keyspace
	 * @param type
	 * @param value
	 * @return
	 */
	public static <T> AfterGetEvent<T> afterGet(Object id, String keyspace, Class<T> type, @Nullable T value) {
		return new AfterGetEvent<>(id, keyspace, type, value);
	}

	/**
	 * Create new {@link BeforeInsertEvent}.
	 *
	 * @param id
	 * @param keyspace
	 * @param type
	 * @param value
	 * @return
	 */
	public static <T> BeforeInsertEvent<T> beforeInsert(Object id, String keyspace, Class<? extends T> type, T value) {
		return new BeforeInsertEvent<>(id, keyspace, type, value);
	}

	/**
	 * Create new {@link AfterInsertEvent}.
	 *
	 * @param id
	 * @param keyspace
	 * @param type
	 * @param value
	 * @return
	 */
	public static <T> AfterInsertEvent<T> afterInsert(Object id, String keyspace, Class<? extends T> type, T value) {
		return new AfterInsertEvent<>(id, keyspace, type, value);
	}

	/**
	 * Create new {@link BeforeUpdateEvent}.
	 *
	 * @param id
	 * @param keyspace
	 * @param type
	 * @param value
	 * @return
	 */
	public static <T> BeforeUpdateEvent<T> beforeUpdate(Object id, String keyspace, Class<? extends T> type, T value) {
		return new BeforeUpdateEvent<>(id, keyspace, type, value);
	}

	/**
	 * Create new {@link AfterUpdateEvent}.
	 *
	 * @param id
	 * @param keyspace
	 * @param type
	 * @param actualValue
	 * @param previousValue
	 * @return
	 */
	public static <T> AfterUpdateEvent<T> afterUpdate(Object id, String keyspace, Class<? extends T> type, T actualValue,
			@Nullable Object previousValue) {
		return new AfterUpdateEvent<>(id, keyspace, type, actualValue, previousValue);
	}

	/**
	 * Create new {@link BeforeDropKeySpaceEvent}.
	 *
	 * @param keyspace
	 * @param type
	 * @return
	 */
	public static <T> BeforeDropKeySpaceEvent<T> beforeDropKeySpace(String keyspace, Class<? extends T> type) {
		return new BeforeDropKeySpaceEvent<>(keyspace, type);
	}

	/**
	 * Create new {@link AfterDropKeySpaceEvent}.
	 *
	 * @param keyspace
	 * @param type
	 * @return
	 */
	public static <T> AfterDropKeySpaceEvent<T> afterDropKeySpace(String keyspace, Class<? extends T> type) {
		return new AfterDropKeySpaceEvent<>(keyspace, type);
	}

	/**
	 * Create new {@link BeforeDeleteEvent}.
	 *
	 * @param id
	 * @param keyspace
	 * @param type
	 * @return
	 */
	public static <T> BeforeDeleteEvent<T> beforeDelete(Object id, String keyspace, Class<? extends T> type) {
		return new BeforeDeleteEvent<>(id, keyspace, type);
	}

	/**
	 * Create new {@link AfterDeleteEvent}.
	 *
	 * @param id
	 * @param keyspace
	 * @param type
	 * @param value
	 * @return
	 */
	public static <T> AfterDeleteEvent<T> afterDelete(Object id, String keyspace, Class<? extends T> type,
			@Nullable T value) {
		return new AfterDeleteEvent<>(id, keyspace, type, value);
	}

	/**
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	abstract static class KeyBasedEvent<T> extends KeyValueEvent<T> {

		private Object key;
		private Class<? extends T> type;

		KeyBasedEvent(Object key, String keyspace, Class<? extends T> type) {

			super(type, keyspace);
			this.key = key;
			this.type = type;
		}

		public Object getKey() {
			return key;
		}

		@Override
		public Object getSource() {
			return getKey();
		}

		/**
		 * Get the type of the element the {@link KeyValueEvent} refers to.
		 *
		 * @return
		 */
		public Class<? extends T> getType() {
			return type;
		}
	}

	/**
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	abstract static class KeyBasedEventWithPayload<T> extends KeyBasedEvent<T> {

		private final @Nullable T payload;

		KeyBasedEventWithPayload(Object key, String keyspace, Class<? extends T> type, @Nullable T payload) {
			super(key, keyspace, type);
			this.payload = payload;
		}

		/**
		 * Get the value of the element the {@link KeyValueEvent} refers to. Can be {@literal null}.
		 *
		 * @return
		 */
		public @Nullable T getPayload() {
			return payload;
		}
	}

	/**
	 * {@link KeyValueEvent} raised before loading an object by its {@literal key}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class BeforeGetEvent<T> extends KeyBasedEvent<T> {

		protected BeforeGetEvent(Object key, String keyspace, Class<T> type) {
			super(key, keyspace, type);
		}

	}

	/**
	 * {@link KeyValueEvent} after loading an object by its {@literal key}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class AfterGetEvent<T> extends KeyBasedEventWithPayload<T> {

		protected AfterGetEvent(Object key, String keyspace, Class<T> type, @Nullable T payload) {
			super(key, keyspace, type, payload);
		}

	}

	/**
	 * {@link KeyValueEvent} before inserting an object by with a given {@literal key}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class BeforeInsertEvent<T> extends KeyBasedEventWithPayload<T> {

		public BeforeInsertEvent(Object key, String keyspace, Class<? extends T> type, @Nullable T payload) {
			super(key, keyspace, type, payload);

		}
	}

	/**
	 * {@link KeyValueEvent} after inserting an object by with a given {@literal key}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class AfterInsertEvent<T> extends KeyBasedEventWithPayload<T> {

		public AfterInsertEvent(Object key, String keyspace, Class<? extends T> type, @Nullable T payload) {
			super(key, keyspace, type, payload);
		}
	}

	/**
	 * {@link KeyValueEvent} before updating an object by with a given {@literal key}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class BeforeUpdateEvent<T> extends KeyBasedEventWithPayload<T> {

		public BeforeUpdateEvent(Object key, String keyspace, Class<? extends T> type, @Nullable T payload) {
			super(key, keyspace, type, payload);
		}
	}

	/**
	 * {@link KeyValueEvent} after updating an object by with a given {@literal key}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class AfterUpdateEvent<T> extends KeyBasedEventWithPayload<T> {

		private final @Nullable Object existing;

		public AfterUpdateEvent(Object key, String keyspace, Class<? extends T> type, T payload,
				@Nullable Object existing) {
			super(key, keyspace, type, payload);
			this.existing = existing;
		}

		/**
		 * Get the value before update. Can be {@literal null}.
		 *
		 * @return
		 */
		public @Nullable Object before() {
			return existing;
		}

		/**
		 * Get the current value.
		 *
		 * @return can be {@literal null}.
		 */
		public @Nullable T after() {
			return getPayload();
		}
	}

	/**
	 * {@link KeyValueEvent} before removing an object by with a given {@literal key}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class BeforeDeleteEvent<T> extends KeyBasedEvent<T> {

		public BeforeDeleteEvent(Object key, String keyspace, Class<? extends T> type) {
			super(key, keyspace, type);
		}
	}

	/**
	 * {@link KeyValueEvent} after removing an object by with a given {@literal key}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class AfterDeleteEvent<T> extends KeyBasedEventWithPayload<T> {

		public AfterDeleteEvent(Object key, String keyspace, Class<? extends T> type, @Nullable T payload) {
			super(key, keyspace, type, payload);
		}
	}

	/**
	 * {@link KeyValueEvent} before removing all elements in a given {@literal keyspace}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class BeforeDropKeySpaceEvent<T> extends KeyValueEvent<T> {

		public BeforeDropKeySpaceEvent(String keyspace, Class<? extends T> type) {
			super(type, keyspace);
		}

		@Override
		@SuppressWarnings("unchecked")
		public Class<T> getSource() {
			return (Class<T>) super.getSource();
		}

	}

	/**
	 * {@link KeyValueEvent} after removing all elements in a given {@literal keyspace}.
	 *
	 * @author Christoph Strobl
	 * @param <T>
	 */
	@SuppressWarnings("serial")
	public static class AfterDropKeySpaceEvent<T> extends KeyValueEvent<T> {

		public AfterDropKeySpaceEvent(String keyspace, Class<? extends T> type) {
			super(type, keyspace);
		}

		@Override
		@SuppressWarnings("unchecked")
		public Class<T> getSource() {
			return (Class<T>) super.getSource();
		}
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/event/package-info.java
================================================
/**
 * Support classes for key-value events, like standard persistence lifecycle events.
 */
@org.jspecify.annotations.NullMarked
package org.springframework.data.keyvalue.core.event;


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/AnnotationBasedKeySpaceResolver.java
================================================
/*
 * Copyright 2015-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.mapping;

import org.jspecify.annotations.Nullable;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.data.annotation.Persistent;
import org.springframework.data.keyvalue.annotation.KeySpace;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

/**
 * {@link AnnotationBasedKeySpaceResolver} looks up {@link Persistent} and checks for presence of either meta or direct
 * usage of {@link KeySpace}. If non found it will default the keyspace to {@link Class#getName()}.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 * @author Mark Paluch
 */
public enum AnnotationBasedKeySpaceResolver implements KeySpaceResolver {

	INSTANCE;

	@Override
	public @Nullable String resolveKeySpace(Class<?> type) {

		Assert.notNull(type, "Type for keyspace for null");

		Class<?> userClass = ClassUtils.getUserClass(type);
		Object keySpace = getKeySpace(userClass);

		return keySpace != null ? keySpace.toString() : null;
	}


	private static @Nullable Object getKeySpace(Class<?> type) {

		MergedAnnotation<KeySpace> annotation = MergedAnnotations
				.from(type, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).get(KeySpace.class);

		if (annotation.isPresent()) {
			return annotation.getValue("value").orElse(null);
		}

		return null;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/BasicKeyValuePersistentEntity.java
================================================
/*
 * Copyright 2015-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.mapping;

import org.jspecify.annotations.Nullable;

import org.springframework.data.core.TypeInformation;
import org.springframework.data.expression.ValueExpression;
import org.springframework.data.expression.ValueExpressionParser;
import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

/**
 * {@link KeyValuePersistentEntity} implementation that adds specific meta-data such as the {@literal keySpace}.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 * @author Mark Paluch
 * @param <T>
 */
public class BasicKeyValuePersistentEntity<T, P extends KeyValuePersistentProperty<P>>
		extends BasicPersistentEntity<T, P> implements KeyValuePersistentEntity<T, P> {

	private static final ValueExpressionParser PARSER = ValueExpressionParser.create(SpelExpressionParser::new);

	private final @Nullable ValueExpression keyspaceExpression;
	private final String keyspace;

	/**
	 * @param information must not be {@literal null}.
	 * @since 3.1
	 */
	public BasicKeyValuePersistentEntity(TypeInformation<T> information) {
		this(information, (String) null);
	}

	/**
	 * @param information must not be {@literal null}.
	 * @param keySpaceResolver can be {@literal null}.
	 */
	public BasicKeyValuePersistentEntity(TypeInformation<T> information, @Nullable KeySpaceResolver keySpaceResolver) {
		this(information, keySpaceResolver != null ? keySpaceResolver.resolveKeySpace(information.getType()) : null);
	}

	private BasicKeyValuePersistentEntity(TypeInformation<T> information, @Nullable String keyspace) {

		super(information);

		if (StringUtils.hasText(keyspace)) {

			this.keyspace = keyspace;
			this.keyspaceExpression = null;
		} else {

			Class<T> type = information.getType();
			String detectedKeyspace = AnnotationBasedKeySpaceResolver.INSTANCE.resolveKeySpace(type);

			if (StringUtils.hasText(detectedKeyspace)) {

				this.keyspace = detectedKeyspace;
				this.keyspaceExpression = detectExpression(detectedKeyspace);
			} else {

				this.keyspace = ClassNameKeySpaceResolver.INSTANCE.resolveKeySpace(type);
				this.keyspaceExpression = null;
			}
		}
	}

	/**
	 * Returns a SpEL {@link Expression} if the given {@link String} is actually an expression that does not evaluate to a
	 * {@link LiteralExpression} (indicating that no subsequent evaluation is necessary).
	 *
	 * @param potentialExpression must not be {@literal null}
	 * @return the parsed {@link Expression} or {@literal null}.
	 */

	private static @Nullable ValueExpression detectExpression(String potentialExpression) {

		ValueExpression expression = PARSER.parse(potentialExpression);
		return expression.isLiteral() ? null : expression;
	}

	@Override
	public String getKeySpace() {
		return keyspaceExpression == null //
				? keyspace //
				: ObjectUtils.nullSafeToString(keyspaceExpression.evaluate(getValueEvaluationContext(null)));
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/ClassNameKeySpaceResolver.java
================================================
/*
 * Copyright 2015-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.mapping;

import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

/**
 * Most trivial implementation of {@link KeySpaceResolver} returning the {@link Class#getName()}.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 */
public enum ClassNameKeySpaceResolver implements KeySpaceResolver {

	INSTANCE;

	@Override
	public String resolveKeySpace(Class<?> type) {

		Assert.notNull(type, "Type must not be null");
		return ClassUtils.getUserClass(type).getName();
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/KeySpaceResolver.java
================================================
/*
 * Copyright 2015-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.mapping;

import org.jspecify.annotations.Nullable;

/**
 * {@link KeySpaceResolver} determines the {@literal keyspace} a given type is assigned to. A keyspace in this context
 * is a specific region/collection/grouping of elements sharing a common keyrange.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 */
public interface KeySpaceResolver {

	/**
	 * Determine the {@literal keySpace} to use for a given type.
	 *
	 * @param type must not be {@literal null}.
	 * @return
	 */
	@Nullable
	String resolveKeySpace(Class<?> type);
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentEntity.java
================================================
/*
 * Copyright 2015-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.mapping;

import org.jspecify.annotations.Nullable;

import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.model.MutablePersistentEntity;

/**
 * KeyValue-specific extension of {@link PersistentEntity} declaring a {@literal keySpace}.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 * @param <T>
 */
public interface KeyValuePersistentEntity<T, P extends KeyValuePersistentProperty<P>>
		extends MutablePersistentEntity<T, P> {

	/**
	 * Get the {@literal keySpace} a given entity assigns to.
	 *
	 * @return can be {@literal null}.
	 */
	@Nullable
	String getKeySpace();

	/**
	 * Returns the required {@literal keySpace} or throws an {@link IllegalStateException} if the {@literal keySpace} is
	 * not defined.
	 *
	 * @return the {@literal keySpace} property of this {@link PersistentEntity}.
	 * @throws IllegalStateException if the {@literal keySpace} is not defined.
	 * @since 4.0
	 */
	default String getRequiredKeySpace() {

		String keySpace = getKeySpace();

		if (keySpace != null) {
			return keySpace;
		}

		throw new IllegalStateException(String.format("Required keySpace not defined for %s", getType()));
	}

}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentProperty.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.mapping;

import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.SimpleTypeHolder;

/**
 * Most trivial implementation of {@link PersistentProperty}.
 *
 * @author Christoph Strobl
 * @author Mark Paluch
 */
public class KeyValuePersistentProperty<P extends KeyValuePersistentProperty<P>>
		extends AnnotationBasedPersistentProperty<P> {

	public KeyValuePersistentProperty(Property property, PersistentEntity<?, P> owner,
			SimpleTypeHolder simpleTypeHolder) {
		super(property, owner, simpleTypeHolder);
	}

	@Override
	@SuppressWarnings("unchecked")
	protected Association<P> createAssociation() {
		return new Association<>((P) this, null);
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/PrefixKeyspaceResolver.java
================================================
/*
 * Copyright 2022-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.mapping;

import org.springframework.util.Assert;

/**
 * {@link KeySpaceResolver} prefixing the {@literal keyspace} with a static prefix after determining the keyspace from a
 * delegate {@link KeySpaceResolver}.
 *
 * @author Mark Paluch
 * @since 3.1
 */
public class PrefixKeyspaceResolver implements KeySpaceResolver {

	private final String prefix;
	private final KeySpaceResolver delegate;

	public PrefixKeyspaceResolver(String prefix, KeySpaceResolver delegate) {

		Assert.notNull(prefix, "Prefix must not be null");
		Assert.notNull(delegate, "Delegate KeySpaceResolver must not be null");

		this.prefix = prefix;
		this.delegate = delegate;
	}

	@Override
	public String resolveKeySpace(Class<?> type) {
		return prefix + delegate.resolveKeySpace(type);
	}

}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/context/KeyValueMappingContext.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.mapping.context;

import java.util.Collections;

import org.jspecify.annotations.Nullable;

import org.springframework.data.core.TypeInformation;
import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity;
import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
import org.springframework.data.mapping.context.AbstractMappingContext;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.SimpleTypeHolder;

/**
 * Default implementation of a {@link MappingContext} using {@link KeyValuePersistentEntity} and
 * {@link KeyValuePersistentProperty} as primary abstractions.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 * @author Mark Paluch
 */
public class KeyValueMappingContext<E extends KeyValuePersistentEntity<?, P>, P extends KeyValuePersistentProperty<P>>
		extends AbstractMappingContext<E, P> {

	private @Nullable KeySpaceResolver keySpaceResolver;

	public KeyValueMappingContext() {
		setSimpleTypeHolder(new KeyValueSimpleTypeHolder());
	}

	/**
	 * Configures the {@link KeySpaceResolver} to be used if not explicit key space is annotated to the domain type.
	 *
	 * @param fallbackKeySpaceResolver can be {@literal null}.
	 * @deprecated since 3.1, use {@link KeySpaceResolver} instead.
	 */
	@Deprecated(since = "3.1")
	public void setFallbackKeySpaceResolver(KeySpaceResolver fallbackKeySpaceResolver) {
		setKeySpaceResolver(fallbackKeySpaceResolver);
	}

	/**
	 * Configures the {@link KeySpaceResolver} to be used. Configuring a {@link KeySpaceResolver} disables SpEL evaluation
	 * abilities.
	 *
	 * @param keySpaceResolver can be {@literal null}.
	 * @since 3.1
	 */
	public void setKeySpaceResolver(KeySpaceResolver keySpaceResolver) {
		this.keySpaceResolver = keySpaceResolver;
	}

	/**
	 * @return the current {@link KeySpaceResolver}. Can be {@literal null}.
	 * @since 3.1
	 */
	public @Nullable KeySpaceResolver getKeySpaceResolver() {
		return keySpaceResolver;
	}

	@Override
	@SuppressWarnings("unchecked")
	protected <T> E createPersistentEntity(TypeInformation<T> typeInformation) {
		return (E) new BasicKeyValuePersistentEntity<T, P>(typeInformation, getKeySpaceResolver());
	}

	@Override
	@SuppressWarnings("unchecked")
	protected P createPersistentProperty(Property property, E owner, SimpleTypeHolder simpleTypeHolder) {
		return (P) new KeyValuePersistentProperty<>(property, owner, simpleTypeHolder);
	}

	/**
	 * @since 2.5.1
	 */
	private static class KeyValueSimpleTypeHolder extends SimpleTypeHolder {

		public KeyValueSimpleTypeHolder() {
			super(Collections.emptySet(), true);
		}

		@Override
		public boolean isSimpleType(Class<?> type) {

			if (type.getName().startsWith("java.") || type.getName().startsWith("javax.")) {
				return true;
			}

			return super.isSimpleType(type);
		}
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/context/package-info.java
================================================
/**
 * Infrastructure for the Key-Value mapping context.
 */
@org.jspecify.annotations.NullMarked
package org.springframework.data.keyvalue.core.mapping.context;


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/package-info.java
================================================
/**
 * Infrastructure for the Key-Value mapping subsystem and keyspace resolution.
 */
@org.jspecify.annotations.NullMarked
package org.springframework.data.keyvalue.core.mapping;


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/package-info.java
================================================
/**
 * Core key/value implementation.
 */
@org.jspecify.annotations.NullMarked
package org.springframework.data.keyvalue.core;


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/query/KeyValueQuery.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.core.query;

import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Sort;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;

/**
 * @author Christoph Strobl
 * @author Mark Paluch
 * @author Marcel Overdijk
 * @param <T> Criteria type
 */
public class KeyValueQuery<T> {

	private Sort sort = Sort.unsorted();
	private long offset = -1;
	private int rows = -1;
	private final @Nullable T criteria;

	/**
	 * Creates new instance of {@link KeyValueQuery}.
	 */
	public KeyValueQuery() {
		this((T) null);
	}

	/**
	 * Creates new instance of {@link KeyValueQuery} with given criteria.
	 *
	 * @param criteria can be {@literal null}.
	 */
	public KeyValueQuery(@Nullable T criteria) {
		this.criteria = criteria;
	}

	/**
	 * Creates new instance of {@link KeyValueQuery} with given criteria and {@link Sort}.
	 *
	 * @param criteria can be {@literal null}.
	 * @param sort must not be {@literal null}.
	 * @since 2.4
	 */
	public KeyValueQuery(@Nullable T criteria, Sort sort) {
		this.criteria = criteria;
		setSort(sort);
	}

	/**
	 * Creates new instance of {@link KeyValueQuery} with given {@link Sort}.
	 *
	 * @param sort must not be {@literal null}.
	 */
	public KeyValueQuery(Sort sort) {
		this();
		setSort(sort);
	}

	/**
	 * Get the criteria object.
	 *
	 * @return
	 * @since 2.0
	 */
	public @Nullable T getCriteria() {
		return criteria;
	}

	/**
	 * Get {@link Sort}.
	 *
	 * @return
	 */
	public Sort getSort() {
		return sort;
	}

	/**
	 * Number of elements to skip.
	 *
	 * @return negative value if not set.
	 */
	public long getOffset() {
		return this.offset;
	}

	/**
	 * Number of elements to read.
	 *
	 * @return negative value if not set.
	 */
	public int getRows() {
		return this.rows;
	}

	/**
	 * Set the number of elements to skip.
	 *
	 * @param offset use negative value for none.
	 */
	public void setOffset(long offset) {
		this.offset = offset;
	}

	/**
	 * Set the number of elements to read.
	 *
	 * @param rows use negative value for all.
	 */
	public void setRows(int rows) {
		this.rows = rows;
	}

	/**
	 * Set {@link Sort} to be applied.
	 *
	 * @param sort
	 */
	public void setSort(Sort sort) {

		Assert.notNull(sort, "Sort must not be null");

		this.sort = sort;
	}

	/**
	 * Add given {@link Sort}.
	 *
	 * @param sort must not be {@literal null}.
	 * @return
	 */
	@Contract("_ -> this")
	public KeyValueQuery<T> orderBy(Sort sort) {

		Assert.notNull(sort, "Sort must not be null");

		if (this.sort.isSorted()) {
			this.sort = this.sort.and(sort);
		} else {
			this.sort = sort;
		}

		return this;
	}

	/**
	 * @see KeyValueQuery#setOffset(long)
	 * @param offset
	 * @return
	 */
	@Contract("_ -> this")
	public KeyValueQuery<T> skip(long offset) {

		setOffset(offset);

		return this;
	}

	/**
	 * @see KeyValueQuery#setRows(int)
	 * @param rows
	 * @return
	 */
	@Contract("_ -> this")
	public KeyValueQuery<T> limit(int rows) {
		setRows(rows);
		return this;
	}

}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/core/query/package-info.java
================================================
/**
 * Key/value specific query and abstractions.
 */
@org.jspecify.annotations.NullMarked
package org.springframework.data.keyvalue.core.query;


================================================
FILE: src/main/java/org/springframework/data/keyvalue/repository/KeyValueRepository.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.repository;

import org.springframework.data.repository.ListCrudRepository;
import org.springframework.data.repository.ListPagingAndSortingRepository;

/**
 * @author Christoph Strobl
 * @param <T>
 * @param <ID>
 */
public interface KeyValueRepository<T, ID> extends ListCrudRepository<T, ID>, ListPagingAndSortingRepository<T, ID> {

}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.repository.config;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;

import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
import org.springframework.data.keyvalue.repository.KeyValueRepository;
import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery;
import org.springframework.data.keyvalue.repository.query.SpelQueryCreator;
import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean;
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
import org.springframework.data.repository.config.RepositoryConfigurationSource;

/**
 * {@link RepositoryConfigurationExtension} for {@link KeyValueRepository}.
 *
 * @author Christoph Strobl
 * @author Oliver Gierke
 * @author Mark Paluch
 */
public abstract class KeyValueRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {

	protected static final String MAPPING_CONTEXT_BEAN_NAME = "keyValueMappingContext";
	protected static final String KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE = "keyValueTemplateRef";

	@Override
	public String getRepositoryFactoryBeanClassName() {
		return KeyValueRepositoryFactoryBean.class.getName();
	}

	@Override
	public String getModuleName() {
		return "KeyValue";
	}

	@Override
	protected String getModulePrefix() {
		return getModuleIdentifier();
	}

	@Override
	protected Collection<Class<?>> getIdentifyingTypes() {
		return Collections.singleton(KeyValueRepository.class);
	}

	@Override
	public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) {

		AnnotationAttributes attributes = config.getAttributes();

		builder.addPropertyReference("keyValueOperations", attributes.getString(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE));
		builder.addPropertyValue("queryCreator", getQueryCreatorType(config));
		builder.addPropertyValue("queryType", getQueryType(config));
		builder.addPropertyReference("mappingContext", getMappingContextBeanRef());
	}

	/**
	 * Detects the query creator type to be used for the factory to set. Will lookup a {@link QueryCreatorType} annotation
	 * on the {@code @Enable}-annotation or use {@link SpelQueryCreator} if not found.
	 *
	 * @param config must not be {@literal null}.
	 * @return
	 */
	private static Class<?> getQueryCreatorType(AnnotationRepositoryConfigurationSource config) {

		AnnotationMetadata amd = (AnnotationMetadata) config.getSource();
		MergedAnnotation<QueryCreatorType> queryCreator = amd.getAnnotations().get(QueryCreatorType.class);
		Class<?> queryCreatorType = queryCreator.isPresent() ? queryCreator.getClass("value") : Class.class;

		if (queryCreatorType == Class.class) {
			return SpelQueryCreator.class;
		}

		return queryCreatorType;
	}

	/**
	 * Detects the query creator type to be used for the factory to set. Will lookup a {@link QueryCreatorType} annotation
	 * on the {@code @Enable}-annotation or use {@link SpelQueryCreator} if not found.
	 *
	 * @param config
	 * @return
	 */
	private static Class<?> getQueryType(AnnotationRepositoryConfigurationSource config) {

		AnnotationMetadata metadata = config.getEnableAnnotationMetadata();

		Map<String, Object> queryCreatorAnnotationAttributes = metadata
				.getAnnotationAttributes(QueryCreatorType.class.getName());

		if (queryCreatorAnnotationAttributes == null) {
			return KeyValuePartTreeQuery.class;
		}

		AnnotationAttributes queryCreatorAttributes = new AnnotationAttributes(queryCreatorAnnotationAttributes);
		return queryCreatorAttributes.getClass("repositoryQueryType");
	}

	@Override
	public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) {

		super.registerBeansForRoot(registry, configurationSource);

		registerIfNotAlreadyRegistered(() -> {

			RootBeanDefinition mappingContext = new RootBeanDefinition(KeyValueMappingContext.class);
			mappingContext.setSource(configurationSource.getSource());

			return mappingContext;

		}, registry, getMappingContextBeanRef(), configurationSource);

		Optional<String> keyValueTemplateName = configurationSource.getAttribute(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE);

		// No custom template reference configured and no matching bean definition found
		if (keyValueTemplateName.isPresent() && getDefaultKeyValueTemplateRef().equals(keyValueTemplateName.get())
				&& !registry.containsBeanDefinition(keyValueTemplateName.get())) {

			AbstractBeanDefinition beanDefinition = getDefaultKeyValueTemplateBeanDefinition(configurationSource);

			if (beanDefinition != null && configurationSource.getSource() != null) {
				registerIfNotAlreadyRegistered(() -> beanDefinition, registry, keyValueTemplateName.get(),
						configurationSource.getSource());
			}
		}
	}

	/**
	 * Get the default {@link RootBeanDefinition} for {@link org.springframework.data.keyvalue.core.KeyValueTemplate}.
	 *
	 * @return {@literal null} to explicitly not register a template.
	 * @see #getDefaultKeyValueTemplateRef()
	 */
	protected @Nullable AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition(
			RepositoryConfigurationSource configurationSource) {
		return null;
	}

	/**
	 * Returns the {@link org.springframework.data.keyvalue.core.KeyValueTemplate} bean name to potentially register a
	 * default {@link org.springframework.data.keyvalue.core.KeyValueTemplate} bean if no bean is registered with the
	 * returned name.
	 *
	 * @return the default {@link org.springframework.data.keyvalue.core.KeyValueTemplate} bean name. Never
	 *         {@literal null}.
	 * @see #getDefaultKeyValueTemplateBeanDefinition(RepositoryConfigurationSource)
	 */
	protected abstract String getDefaultKeyValueTemplateRef();

	/**
	 * Returns the {@link org.springframework.data.mapping.context.MappingContext} bean name to potentially register a
	 * default mapping context bean if no bean is registered with the returned name. Defaults to
	 * {@link MAPPING_CONTEXT_BEAN_NAME}.
	 *
	 * @return the {@link org.springframework.data.mapping.context.MappingContext} bean name. Never {@literal null}.
	 * @since 2.0
	 */
	protected String getMappingContextBeanRef() {
		return MAPPING_CONTEXT_BEAN_NAME;
	}
}


================================================
FILE: src/main/java/org/springframework/data/keyvalue/repository/config/QueryCreatorType.java
================================================
/*
 * Copyright 2014-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.keyvalue.repository.config;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.repository.query.parser.AbstractQueryCreator;

/**
 * Annotation to customize the qu
Download .txt
gitextract_fy98wr_9/

├── .github/
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── README.template.adoc
│   ├── dco.yml
│   └── workflows/
│       ├── ci.yml
│       ├── codeql.yml
│       ├── project.yml
│       └── snapshots.yml
├── .gitignore
├── .mvn/
│   ├── extensions.xml
│   ├── jvm.config
│   └── wrapper/
│       ├── maven-wrapper.jar
│       └── maven-wrapper.properties
├── CI.adoc
├── CONTRIBUTING.adoc
├── LICENSE.txt
├── README.adoc
├── SECURITY.adoc
├── mvnw
├── mvnw.cmd
├── package.json
├── pom.xml
├── settings.xml
└── src/
    ├── main/
    │   ├── antora/
    │   │   ├── antora-playbook.yml
    │   │   ├── antora.yml
    │   │   ├── modules/
    │   │   │   └── ROOT/
    │   │   │       ├── nav.adoc
    │   │   │       └── pages/
    │   │   │           ├── commons/
    │   │   │           │   └── upgrade.adoc
    │   │   │           ├── index.adoc
    │   │   │           ├── keyvalue/
    │   │   │           │   ├── repository/
    │   │   │           │   │   └── map-repositories.adoc
    │   │   │           │   ├── template.adoc
    │   │   │           │   └── value-expressions.adoc
    │   │   │           ├── keyvalue.adoc
    │   │   │           ├── repositories/
    │   │   │           │   ├── core-concepts.adoc
    │   │   │           │   ├── core-domain-events.adoc
    │   │   │           │   ├── core-extensions.adoc
    │   │   │           │   ├── create-instances.adoc
    │   │   │           │   ├── custom-implementations.adoc
    │   │   │           │   ├── definition.adoc
    │   │   │           │   ├── null-handling.adoc
    │   │   │           │   ├── object-mapping.adoc
    │   │   │           │   ├── projections.adoc
    │   │   │           │   ├── query-keywords-reference.adoc
    │   │   │           │   ├── query-methods-details.adoc
    │   │   │           │   └── query-return-types-reference.adoc
    │   │   │           └── repositories.adoc
    │   │   └── resources/
    │   │       └── antora-resources/
    │   │           └── antora.yml
    │   ├── java/
    │   │   └── org/
    │   │       └── springframework/
    │   │           └── data/
    │   │               ├── keyvalue/
    │   │               │   ├── annotation/
    │   │               │   │   ├── KeySpace.java
    │   │               │   │   └── package-info.java
    │   │               │   ├── aot/
    │   │               │   │   ├── KeyValueRuntimeHints.java
    │   │               │   │   └── package-info.java
    │   │               │   ├── core/
    │   │               │   │   ├── AbstractKeyValueAdapter.java
    │   │               │   │   ├── CriteriaAccessor.java
    │   │               │   │   ├── DefaultIdentifierGenerator.java
    │   │               │   │   ├── ForwardingCloseableIterator.java
    │   │               │   │   ├── GeneratingIdAccessor.java
    │   │               │   │   ├── IdentifierGenerator.java
    │   │               │   │   ├── IterableConverter.java
    │   │               │   │   ├── KeyValueAdapter.java
    │   │               │   │   ├── KeyValueCallback.java
    │   │               │   │   ├── KeyValueOperations.java
    │   │               │   │   ├── KeyValuePersistenceExceptionTranslator.java
    │   │               │   │   ├── KeyValueTemplate.java
    │   │               │   │   ├── PathSortAccessor.java
    │   │               │   │   ├── PredicateQueryEngine.java
    │   │               │   │   ├── PropertyPathComparator.java
    │   │               │   │   ├── QueryEngine.java
    │   │               │   │   ├── QueryEngineFactory.java
    │   │               │   │   ├── SimplePropertyPathAccessor.java
    │   │               │   │   ├── SortAccessor.java
    │   │               │   │   ├── SpelCriteria.java
    │   │               │   │   ├── SpelCriteriaAccessor.java
    │   │               │   │   ├── SpelPropertyComparator.java
    │   │               │   │   ├── SpelQueryEngine.java
    │   │               │   │   ├── SpelSortAccessor.java
    │   │               │   │   ├── UncategorizedKeyValueException.java
    │   │               │   │   ├── event/
    │   │               │   │   │   ├── KeyValueEvent.java
    │   │               │   │   │   └── package-info.java
    │   │               │   │   ├── mapping/
    │   │               │   │   │   ├── AnnotationBasedKeySpaceResolver.java
    │   │               │   │   │   ├── BasicKeyValuePersistentEntity.java
    │   │               │   │   │   ├── ClassNameKeySpaceResolver.java
    │   │               │   │   │   ├── KeySpaceResolver.java
    │   │               │   │   │   ├── KeyValuePersistentEntity.java
    │   │               │   │   │   ├── KeyValuePersistentProperty.java
    │   │               │   │   │   ├── PrefixKeyspaceResolver.java
    │   │               │   │   │   ├── context/
    │   │               │   │   │   │   ├── KeyValueMappingContext.java
    │   │               │   │   │   │   └── package-info.java
    │   │               │   │   │   └── package-info.java
    │   │               │   │   ├── package-info.java
    │   │               │   │   └── query/
    │   │               │   │       ├── KeyValueQuery.java
    │   │               │   │       └── package-info.java
    │   │               │   └── repository/
    │   │               │       ├── KeyValueRepository.java
    │   │               │       ├── config/
    │   │               │       │   ├── KeyValueRepositoryConfigurationExtension.java
    │   │               │       │   ├── QueryCreatorType.java
    │   │               │       │   └── package-info.java
    │   │               │       ├── package-info.java
    │   │               │       ├── query/
    │   │               │       │   ├── CachingKeyValuePartTreeQuery.java
    │   │               │       │   ├── KeyValuePartTreeQuery.java
    │   │               │       │   ├── PredicateQueryCreator.java
    │   │               │       │   ├── SpelQueryCreator.java
    │   │               │       │   └── package-info.java
    │   │               │       └── support/
    │   │               │           ├── KeyValueQuerydslUtils.java
    │   │               │           ├── KeyValueRepositoryFactory.java
    │   │               │           ├── KeyValueRepositoryFactoryBean.java
    │   │               │           ├── QuerydslKeyValuePredicateExecutor.java
    │   │               │           ├── QuerydslKeyValueRepository.java
    │   │               │           ├── SimpleKeyValueRepository.java
    │   │               │           └── package-info.java
    │   │               └── map/
    │   │                   ├── KeySpaceStore.java
    │   │                   ├── MapKeySpaceStore.java
    │   │                   ├── MapKeyValueAdapter.java
    │   │                   ├── package-info.java
    │   │                   └── repository/
    │   │                       └── config/
    │   │                           ├── EnableMapRepositories.java
    │   │                           ├── MapRepositoriesRegistrar.java
    │   │                           ├── MapRepositoryConfigurationExtension.java
    │   │                           └── package-info.java
    │   └── resources/
    │       ├── META-INF/
    │       │   ├── spring/
    │       │   │   └── aot.factories
    │       │   └── spring.factories
    │       ├── license.txt
    │       └── notice.txt
    └── test/
        ├── java/
        │   └── org/
        │       └── springframework/
        │           └── data/
        │               ├── keyvalue/
        │               │   ├── CustomKeySpaceAnnotationWithAliasFor.java
        │               │   ├── Person.java
        │               │   ├── SubclassOfTypeWithCustomComposedKeySpaceAnnotation.java
        │               │   ├── TypeWithCustomComposedKeySpaceAnnotationUsingAliasFor.java
        │               │   ├── TypeWithDirectKeySpaceAnnotation.java
        │               │   ├── TypeWithInhteritedPersistentAnnotationNotHavingKeySpace.java
        │               │   ├── TypeWithPersistentAnnotationNotHavingKeySpace.java
        │               │   ├── core/
        │               │   │   ├── DefaultIdentifierGeneratorUnitTests.java
        │               │   │   ├── ForwardingCloseableIteratorUnitTests.java
        │               │   │   ├── IterableConverterUnitTests.java
        │               │   │   ├── KeyValuePersistenceExceptionTranslatorUnitTests.java
        │               │   │   ├── KeyValueTemplateTests.java
        │               │   │   ├── KeyValueTemplateUnitTests.java
        │               │   │   ├── PredicateQueryEngineUnitTests.java
        │               │   │   ├── PropertyPathComparatorUnitTests.java
        │               │   │   ├── SpelPropertyComparatorUnitTests.java
        │               │   │   ├── SpelQueryEngineUnitTests.java
        │               │   │   └── mapping/
        │               │   │       ├── AnnotationBasedKeySpaceResolverUnitTests.java
        │               │   │       ├── BasicKeyValuePersistentEntityUnitTests.java
        │               │   │       ├── PrefixKeyspaceResolverUnitTests.java
        │               │   │       └── context/
        │               │   │           └── KeyValueMappingContextUnitTests.java
        │               │   └── repository/
        │               │       ├── MapRepositoriesRegistrarUnitTests.java
        │               │       ├── SimpleKeyValueRepositoryUnitTests.java
        │               │       ├── query/
        │               │       │   ├── AbstractQueryCreatorTestBase.java
        │               │       │   ├── CachingKeyValuePartTreeQueryUnitTests.java
        │               │       │   ├── KeyValuePartTreeQueryUnitTests.java
        │               │       │   ├── PredicateQueryCreatorUnitTests.java
        │               │       │   └── SpelQueryCreatorUnitTests.java
        │               │       └── support/
        │               │           ├── KeyValueQuerydslUtilsUnitTests.java
        │               │           └── KeyValueRepositoryFactoryBeanUnitTests.java
        │               └── map/
        │                   ├── AbstractRepositoryUnitTests.java
        │                   ├── CachingQuerySimpleKeyValueRepositoryUnitTests.java
        │                   ├── MapDbIntegrationTests.java
        │                   ├── MapKeyValueAdapterUnitTests.java
        │                   ├── QuerydslKeyValuePredicateExecutorUnitTests.java
        │                   ├── SimpleKeyValueRepositoryUnitTests.java
        │                   └── repository/
        │                       └── config/
        │                           ├── MapRepositoriesConfigurationExtensionIntegrationTests.java
        │                           ├── MapRepositoryRegistrarWithFullDefaultingIntegrationTests.java
        │                           └── MapRepositoryRegistrarWithTemplateDefinitionIntegrationTests.java
        └── resources/
            └── logback.xml
Download .txt
SYMBOL INDEX (1105 symbols across 91 files)

FILE: src/main/java/org/springframework/data/keyvalue/aot/KeyValueRuntimeHints.java
  class KeyValueRuntimeHints (line 35) | class KeyValueRuntimeHints implements RuntimeHintsRegistrar {
    method registerHints (line 37) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/AbstractKeyValueAdapter.java
  class AbstractKeyValueAdapter (line 31) | public abstract class AbstractKeyValueAdapter implements KeyValueAdapter {
    method AbstractKeyValueAdapter (line 38) | protected AbstractKeyValueAdapter() {
    method AbstractKeyValueAdapter (line 48) | protected AbstractKeyValueAdapter(SortAccessor<Comparator<?>> sortAcce...
    method AbstractKeyValueAdapter (line 57) | protected AbstractKeyValueAdapter(@Nullable QueryEngine<? extends KeyV...
    method getQueryEngine (line 68) | protected QueryEngine<? extends KeyValueAdapter, ?, ?> getQueryEngine() {
    method get (line 72) | @Override
    method delete (line 77) | @Override
    method find (line 82) | @Override
    method find (line 87) | @Override
    method count (line 92) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/CriteriaAccessor.java
  type CriteriaAccessor (line 28) | public interface CriteriaAccessor<T> {
    method resolve (line 39) | @Nullable

FILE: src/main/java/org/springframework/data/keyvalue/core/DefaultIdentifierGenerator.java
  type DefaultIdentifierGenerator (line 36) | enum DefaultIdentifierGenerator implements IdentifierGenerator {
    method generateIdentifierOfType (line 42) | @Override
    method getSecureRandom (line 63) | private SecureRandom getSecureRandom() {
    class OsTools (line 93) | private static class OsTools {
      method secureRandomAlgorithmNames (line 101) | static List<String> secureRandomAlgorithmNames() {

FILE: src/main/java/org/springframework/data/keyvalue/core/ForwardingCloseableIterator.java
  class ForwardingCloseableIterator (line 32) | public class ForwardingCloseableIterator<T> implements CloseableIterator...
    method ForwardingCloseableIterator (line 42) | public ForwardingCloseableIterator(Iterator<? extends T> delegate) {
    method ForwardingCloseableIterator (line 53) | public ForwardingCloseableIterator(Iterator<? extends T> delegate, @Nu...
    method hasNext (line 61) | @Override
    method next (line 66) | @Override
    method close (line 71) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/GeneratingIdAccessor.java
  class GeneratingIdAccessor (line 32) | class GeneratingIdAccessor implements IdentifierAccessor {
    method GeneratingIdAccessor (line 46) | GeneratingIdAccessor(PersistentPropertyAccessor<?> accessor, Persisten...
    method getIdentifier (line 58) | @Override
    method getOrGenerateIdentifier (line 69) | Object getOrGenerateIdentifier() {

FILE: src/main/java/org/springframework/data/keyvalue/core/IdentifierGenerator.java
  type IdentifierGenerator (line 26) | public interface IdentifierGenerator {
    method generateIdentifierOfType (line 34) | <T> T generateIdentifierOfType(TypeInformation<T> type);

FILE: src/main/java/org/springframework/data/keyvalue/core/IterableConverter.java
  class IterableConverter (line 32) | public final class IterableConverter {
    method IterableConverter (line 34) | private IterableConverter() {}
    method toList (line 42) | @Contract("_ -> !null")

FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java
  type KeyValueAdapter (line 33) | public interface KeyValueAdapter extends DisposableBean {
    method put (line 42) | @Nullable Object put(Object id, Object item, String keyspace);
    method contains (line 51) | boolean contains(Object id, String keyspace);
    method get (line 60) | @Nullable
    method get (line 72) | <T> @Nullable T get(Object id, String keyspace, Class<T> type);
    method delete (line 81) | @Nullable
    method delete (line 93) | <T> @Nullable T delete(Object id, String keyspace, Class<T> type);
    method getAllOf (line 101) | Iterable<Object> getAllOf(String keyspace);
    method getAllOf (line 111) | @SuppressWarnings("unchecked")
    method entries (line 122) | CloseableIterator<Map.Entry<Object, Object>> entries(String keyspace);
    method entries (line 132) | @SuppressWarnings("unchecked")
    method deleteAllOf (line 142) | void deleteAllOf(String keyspace);
    method clear (line 147) | void clear();
    method find (line 156) | default Iterable<?> find(KeyValueQuery<?> query, String keyspace) {
    method find (line 167) | <T> Iterable<T> find(KeyValueQuery<?> query, String keyspace, Class<T>...
    method count (line 175) | long count(String keyspace);
    method count (line 184) | long count(KeyValueQuery<?> query, String keyspace);
    method exists (line 194) | default boolean exists(KeyValueQuery<?> query, String keyspace) {

FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValueCallback.java
  type KeyValueCallback (line 28) | public interface KeyValueCallback<T> {
    method doInKeyValue (line 37) | @Nullable

FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java
  type KeyValueOperations (line 33) | public interface KeyValueOperations extends DisposableBean {
    method insert (line 41) | <T> T insert(T objectToInsert);
    method insert (line 50) | <T> T insert(Object id, T objectToInsert);
    method findAll (line 59) | <T> Iterable<T> findAll(Class<T> type);
    method findAll (line 69) | <T> Iterable<T> findAll(Sort sort, Class<T> type);
    method findById (line 79) | <T> Optional<T> findById(Object id, Class<T> type);
    method execute (line 88) | <T> @Nullable T execute(KeyValueCallback<T> action);
    method find (line 98) | <T> Iterable<T> find(KeyValueQuery<?> query, Class<T> type);
    method findInRange (line 109) | <T> Iterable<T> findInRange(long offset, int rows, Class<T> type);
    method findInRange (line 121) | <T> Iterable<T> findInRange(long offset, int rows, Sort sort, Class<T>...
    method update (line 127) | <T> T update(T objectToUpdate);
    method update (line 134) | <T> T update(Object id, T objectToUpdate);
    method delete (line 142) | void delete(Class<?> type);
    method delete (line 148) | <T> @Nullable T delete(T objectToDelete);
    method delete (line 157) | <T> @Nullable T delete(Object id, Class<T> type);
    method count (line 166) | long count(Class<?> type);
    method count (line 176) | long count(KeyValueQuery<?> query, Class<?> type);
    method exists (line 186) | boolean exists(KeyValueQuery<?> query, Class<?> type);
    method getMappingContext (line 191) | MappingContext<?, ?> getMappingContext();
    method getKeyValueAdapter (line 197) | KeyValueAdapter getKeyValueAdapter();

FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslator.java
  class KeyValuePersistenceExceptionTranslator (line 33) | public class KeyValuePersistenceExceptionTranslator implements Persisten...
    method translateExceptionIfPossible (line 35) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java
  class KeyValueTemplate (line 52) | public class KeyValueTemplate implements KeyValueOperations, Application...
    method KeyValueTemplate (line 72) | public KeyValueTemplate(KeyValueAdapter adapter) {
    method KeyValueTemplate (line 82) | public KeyValueTemplate(KeyValueAdapter adapter,
    method KeyValueTemplate (line 95) | public KeyValueTemplate(KeyValueAdapter adapter,
    method setExceptionTranslator (line 113) | public void setExceptionTranslator(PersistenceExceptionTranslator exce...
    method setEventTypesToPublish (line 124) | @SuppressWarnings("rawtypes")
    method setApplicationEventPublisher (line 135) | @Override
    method insert (line 140) | @Override
    method insert (line 152) | @Override
    method update (line 178) | @Override
    method update (line 191) | @Override
    method findAll (line 209) | @Override
    method findById (line 230) | @Override
    method delete (line 256) | @Override
    method delete (line 273) | @SuppressWarnings("unchecked")
    method delete (line 283) | @Override
    method count (line 300) | @Override
    method execute (line 308) | @Override
    method executeRequired (line 327) | protected <T> T executeRequired(KeyValueCallback<T> action) {
    method find (line 338) | @Override
    method findAll (line 357) | @SuppressWarnings("rawtypes")
    method findInRange (line 363) | @SuppressWarnings("rawtypes")
    method findInRange (line 369) | @SuppressWarnings("rawtypes")
    method count (line 375) | @Override
    method exists (line 380) | @Override
    method getMappingContext (line 385) | @Override
    method getKeyValueAdapter (line 390) | @Override
    method destroy (line 395) | @Override
    method getKeyValuePersistentEntity (line 400) | private KeyValuePersistentEntity<?, ?> getKeyValuePersistentEntity(Obj...
    method resolveKeySpace (line 405) | private  String resolveKeySpace(Class<?> type) {
    method resolveExceptionIfPossible (line 412) | private RuntimeException resolveExceptionIfPossible(RuntimeException e) {
    method potentiallyPublishEvent (line 418) | @SuppressWarnings("rawtypes")
    method typeCheck (line 430) | private static boolean typeCheck(Class<?> requiredType, @Nullable Obje...

FILE: src/main/java/org/springframework/data/keyvalue/core/PathSortAccessor.java
  class PathSortAccessor (line 31) | public class PathSortAccessor implements SortAccessor<Comparator<?>> {
    method resolve (line 33) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/PredicateQueryEngine.java
  class PredicateQueryEngine (line 36) | public class PredicateQueryEngine extends QueryEngine<KeyValueAdapter, P...
    method PredicateQueryEngine (line 43) | public PredicateQueryEngine() {
    method PredicateQueryEngine (line 50) | public PredicateQueryEngine(SortAccessor<Comparator<?>> sortAccessor) {
    method execute (line 60) | @Override
    method count (line 66) | @Override
    method sortAndFilterMatchingRange (line 72) | @SuppressWarnings({ "unchecked", "rawtypes" })
    method filterMatchingRange (line 84) | @Contract("!null, _, _, _ -> !null")

FILE: src/main/java/org/springframework/data/keyvalue/core/PropertyPathComparator.java
  class PropertyPathComparator (line 35) | public class PropertyPathComparator<T> implements Comparator<T> {
    method PropertyPathComparator (line 47) | public PropertyPathComparator(String path) {
    method compare (line 51) | @Override
    method getCompareValue (line 71) | protected <S> @Nullable Object getCompareValue(S object, PropertyPath ...
    method getComparator (line 75) | @SuppressWarnings("unchecked")
    method asc (line 85) | @Contract("-> this")
    method desc (line 96) | @Contract("-> this")
    method nullsFirst (line 107) | @Contract("-> this")
    method nullsLast (line 118) | @Contract("-> this")

FILE: src/main/java/org/springframework/data/keyvalue/core/QueryEngine.java
  class QueryEngine (line 33) | public abstract class QueryEngine<ADAPTER extends KeyValueAdapter, CRITE...
    method QueryEngine (line 40) | public QueryEngine(@Nullable CriteriaAccessor<CRITERIA> criteriaAccess...
    method execute (line 53) | public Collection<?> execute(KeyValueQuery<?> query, String keyspace) {
    method execute (line 68) | public <T> Collection<T> execute(KeyValueQuery<?> query, String keyspa...
    method count (line 83) | public long count(KeyValueQuery<?> query, String keyspace) {
    method execute (line 97) | public abstract Collection<?> execute(@Nullable CRITERIA criteria, @Nu...
    method execute (line 110) | @SuppressWarnings("unchecked")
    method count (line 121) | public abstract long count(@Nullable CRITERIA criteria, String keyspace);
    method getAdapter (line 128) | protected @Nullable ADAPTER getAdapter() {
    method getRequiredAdapter (line 138) | protected ADAPTER getRequiredAdapter() {
    method registerAdapter (line 152) | @SuppressWarnings("unchecked")

FILE: src/main/java/org/springframework/data/keyvalue/core/QueryEngineFactory.java
  type QueryEngineFactory (line 29) | public interface QueryEngineFactory {
    method create (line 36) | QueryEngine<?, ?, ?> create();

FILE: src/main/java/org/springframework/data/keyvalue/core/SimplePropertyPathAccessor.java
  class SimplePropertyPathAccessor (line 27) | public class SimplePropertyPathAccessor<T> {
    method SimplePropertyPathAccessor (line 31) | public SimplePropertyPathAccessor(Object source) {
    method getValue (line 35) | public @Nullable Object getValue(PropertyPath path) {
    method wrap (line 47) | BeanWrapper wrap(Object o) {

FILE: src/main/java/org/springframework/data/keyvalue/core/SortAccessor.java
  type SortAccessor (line 30) | public interface SortAccessor<T> {
    method resolve (line 39) | @Nullable

FILE: src/main/java/org/springframework/data/keyvalue/core/SpelCriteria.java
  class SpelCriteria (line 30) | public class SpelCriteria {
    method SpelCriteria (line 40) | public SpelCriteria(SpelExpression expression) {
    method SpelCriteria (line 50) | public SpelCriteria(SpelExpression expression, EvaluationContext conte...
    method getContext (line 62) | public EvaluationContext getContext() {
    method getExpression (line 69) | public SpelExpression getExpression() {

FILE: src/main/java/org/springframework/data/keyvalue/core/SpelCriteriaAccessor.java
  class SpelCriteriaAccessor (line 30) | class SpelCriteriaAccessor implements CriteriaAccessor<SpelCriteria> {
    method SpelCriteriaAccessor (line 39) | public SpelCriteriaAccessor(SpelExpressionParser parser) {
    method resolve (line 46) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/SpelPropertyComparator.java
  class SpelPropertyComparator (line 35) | public class SpelPropertyComparator<T> implements Comparator<T> {
    method SpelPropertyComparator (line 53) | public SpelPropertyComparator(String path, SpelExpressionParser parser) {
    method asc (line 67) | @Contract("-> this")
    method desc (line 78) | @Contract("-> this")
    method nullsFirst (line 89) | @Contract("-> this")
    method nullsLast (line 100) | @Contract("-> this")
    method getExpression (line 111) | protected SpelExpression getExpression() {
    method buildExpressionForPath (line 125) | protected String buildExpressionForPath() {
    method compare (line 131) | @Override
    method getPath (line 152) | public String getPath() {

FILE: src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java
  class SpelQueryEngine (line 38) | public class SpelQueryEngine extends QueryEngine<KeyValueAdapter, SpelCr...
    method SpelQueryEngine (line 45) | public SpelQueryEngine() {
    method SpelQueryEngine (line 54) | public SpelQueryEngine(SortAccessor<Comparator<?>> sortAccessor) {
    method execute (line 58) | @Override
    method count (line 64) | @Override
    method sortAndFilterMatchingRange (line 70) | @SuppressWarnings({ "unchecked", "rawtypes" })
    method filterMatchingRange (line 82) | private static <S> List<S> filterMatchingRange(List<S> source, @Nullab...
    method evaluateExpression (line 100) | @SuppressWarnings("NullAway")

FILE: src/main/java/org/springframework/data/keyvalue/core/SpelSortAccessor.java
  class SpelSortAccessor (line 36) | public class SpelSortAccessor implements SortAccessor<Comparator<?>> {
    method SpelSortAccessor (line 45) | public SpelSortAccessor(SpelExpressionParser parser) {
    method resolve (line 51) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/UncategorizedKeyValueException.java
  class UncategorizedKeyValueException (line 27) | public class UncategorizedKeyValueException extends UncategorizedDataAcc...
    method UncategorizedKeyValueException (line 37) | public UncategorizedKeyValueException(String msg, Throwable cause) {

FILE: src/main/java/org/springframework/data/keyvalue/core/event/KeyValueEvent.java
  class KeyValueEvent (line 32) | public class KeyValueEvent<T> extends ApplicationEvent {
    method KeyValueEvent (line 38) | protected KeyValueEvent(Object source, String keyspace) {
    method getKeyspace (line 47) | public String getKeyspace() {
    method toString (line 51) | @Override
    method beforeGet (line 64) | public static <T> BeforeGetEvent<T> beforeGet(Object id, String keyspa...
    method afterGet (line 77) | public static <T> AfterGetEvent<T> afterGet(Object id, String keyspace...
    method beforeInsert (line 90) | public static <T> BeforeInsertEvent<T> beforeInsert(Object id, String ...
    method afterInsert (line 103) | public static <T> AfterInsertEvent<T> afterInsert(Object id, String ke...
    method beforeUpdate (line 116) | public static <T> BeforeUpdateEvent<T> beforeUpdate(Object id, String ...
    method afterUpdate (line 130) | public static <T> AfterUpdateEvent<T> afterUpdate(Object id, String ke...
    method beforeDropKeySpace (line 142) | public static <T> BeforeDropKeySpaceEvent<T> beforeDropKeySpace(String...
    method afterDropKeySpace (line 153) | public static <T> AfterDropKeySpaceEvent<T> afterDropKeySpace(String k...
    method beforeDelete (line 165) | public static <T> BeforeDeleteEvent<T> beforeDelete(Object id, String ...
    method afterDelete (line 178) | public static <T> AfterDeleteEvent<T> afterDelete(Object id, String ke...
    class KeyBasedEvent (line 187) | @SuppressWarnings("serial")
      method KeyBasedEvent (line 193) | KeyBasedEvent(Object key, String keyspace, Class<? extends T> type) {
      method getKey (line 200) | public Object getKey() {
      method getSource (line 204) | @Override
      method getType (line 214) | public Class<? extends T> getType() {
    class KeyBasedEventWithPayload (line 223) | @SuppressWarnings("serial")
      method KeyBasedEventWithPayload (line 228) | KeyBasedEventWithPayload(Object key, String keyspace, Class<? extend...
      method getPayload (line 238) | public @Nullable T getPayload() {
    class BeforeGetEvent (line 249) | @SuppressWarnings("serial")
      method BeforeGetEvent (line 252) | protected BeforeGetEvent(Object key, String keyspace, Class<T> type) {
    class AfterGetEvent (line 264) | @SuppressWarnings("serial")
      method AfterGetEvent (line 267) | protected AfterGetEvent(Object key, String keyspace, Class<T> type, ...
    class BeforeInsertEvent (line 279) | @SuppressWarnings("serial")
      method BeforeInsertEvent (line 282) | public BeforeInsertEvent(Object key, String keyspace, Class<? extend...
    class AfterInsertEvent (line 294) | @SuppressWarnings("serial")
      method AfterInsertEvent (line 297) | public AfterInsertEvent(Object key, String keyspace, Class<? extends...
    class BeforeUpdateEvent (line 308) | @SuppressWarnings("serial")
      method BeforeUpdateEvent (line 311) | public BeforeUpdateEvent(Object key, String keyspace, Class<? extend...
    class AfterUpdateEvent (line 322) | @SuppressWarnings("serial")
      method AfterUpdateEvent (line 327) | public AfterUpdateEvent(Object key, String keyspace, Class<? extends...
      method before (line 338) | public @Nullable Object before() {
      method after (line 347) | public @Nullable T after() {
    class BeforeDeleteEvent (line 358) | @SuppressWarnings("serial")
      method BeforeDeleteEvent (line 361) | public BeforeDeleteEvent(Object key, String keyspace, Class<? extend...
    class AfterDeleteEvent (line 372) | @SuppressWarnings("serial")
      method AfterDeleteEvent (line 375) | public AfterDeleteEvent(Object key, String keyspace, Class<? extends...
    class BeforeDropKeySpaceEvent (line 386) | @SuppressWarnings("serial")
      method BeforeDropKeySpaceEvent (line 389) | public BeforeDropKeySpaceEvent(String keyspace, Class<? extends T> t...
      method getSource (line 393) | @Override
    class AfterDropKeySpaceEvent (line 407) | @SuppressWarnings("serial")
      method AfterDropKeySpaceEvent (line 410) | public AfterDropKeySpaceEvent(String keyspace, Class<? extends T> ty...
      method getSource (line 414) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/AnnotationBasedKeySpaceResolver.java
  type AnnotationBasedKeySpaceResolver (line 34) | public enum AnnotationBasedKeySpaceResolver implements KeySpaceResolver {
    method resolveKeySpace (line 38) | @Override
    method getKeySpace (line 50) | private static @Nullable Object getKeySpace(Class<?> type) {

FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/BasicKeyValuePersistentEntity.java
  class BasicKeyValuePersistentEntity (line 38) | public class BasicKeyValuePersistentEntity<T, P extends KeyValuePersiste...
    method BasicKeyValuePersistentEntity (line 50) | public BasicKeyValuePersistentEntity(TypeInformation<T> information) {
    method BasicKeyValuePersistentEntity (line 58) | public BasicKeyValuePersistentEntity(TypeInformation<T> information, @...
    method BasicKeyValuePersistentEntity (line 62) | private BasicKeyValuePersistentEntity(TypeInformation<T> information, ...
    method detectExpression (line 95) | private static @Nullable ValueExpression detectExpression(String poten...
    method getKeySpace (line 101) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/ClassNameKeySpaceResolver.java
  type ClassNameKeySpaceResolver (line 27) | public enum ClassNameKeySpaceResolver implements KeySpaceResolver {
    method resolveKeySpace (line 31) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/KeySpaceResolver.java
  type KeySpaceResolver (line 27) | public interface KeySpaceResolver {
    method resolveKeySpace (line 35) | @Nullable

FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentEntity.java
  type KeyValuePersistentEntity (line 30) | public interface KeyValuePersistentEntity<T, P extends KeyValuePersisten...
    method getKeySpace (line 38) | @Nullable
    method getRequiredKeySpace (line 49) | default String getRequiredKeySpace() {

FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentProperty.java
  class KeyValuePersistentProperty (line 31) | public class KeyValuePersistentProperty<P extends KeyValuePersistentProp...
    method KeyValuePersistentProperty (line 34) | public KeyValuePersistentProperty(Property property, PersistentEntity<...
    method createAssociation (line 39) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/PrefixKeyspaceResolver.java
  class PrefixKeyspaceResolver (line 27) | public class PrefixKeyspaceResolver implements KeySpaceResolver {
    method PrefixKeyspaceResolver (line 32) | public PrefixKeyspaceResolver(String prefix, KeySpaceResolver delegate) {
    method resolveKeySpace (line 41) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/mapping/context/KeyValueMappingContext.java
  class KeyValueMappingContext (line 40) | public class KeyValueMappingContext<E extends KeyValuePersistentEntity<?...
    method KeyValueMappingContext (line 45) | public KeyValueMappingContext() {
    method setFallbackKeySpaceResolver (line 55) | @Deprecated(since = "3.1")
    method setKeySpaceResolver (line 67) | public void setKeySpaceResolver(KeySpaceResolver keySpaceResolver) {
    method getKeySpaceResolver (line 75) | public @Nullable KeySpaceResolver getKeySpaceResolver() {
    method createPersistentEntity (line 79) | @Override
    method createPersistentProperty (line 85) | @Override
    class KeyValueSimpleTypeHolder (line 94) | private static class KeyValueSimpleTypeHolder extends SimpleTypeHolder {
      method KeyValueSimpleTypeHolder (line 96) | public KeyValueSimpleTypeHolder() {
      method isSimpleType (line 100) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/core/query/KeyValueQuery.java
  class KeyValueQuery (line 29) | public class KeyValueQuery<T> {
    method KeyValueQuery (line 39) | public KeyValueQuery() {
    method KeyValueQuery (line 48) | public KeyValueQuery(@Nullable T criteria) {
    method KeyValueQuery (line 59) | public KeyValueQuery(@Nullable T criteria, Sort sort) {
    method KeyValueQuery (line 69) | public KeyValueQuery(Sort sort) {
    method getCriteria (line 80) | public @Nullable T getCriteria() {
    method getSort (line 89) | public Sort getSort() {
    method getOffset (line 98) | public long getOffset() {
    method getRows (line 107) | public int getRows() {
    method setOffset (line 116) | public void setOffset(long offset) {
    method setRows (line 125) | public void setRows(int rows) {
    method setSort (line 134) | public void setSort(Sort sort) {
    method orderBy (line 147) | @Contract("_ -> this")
    method skip (line 166) | @Contract("_ -> this")
    method limit (line 179) | @Contract("_ -> this")

FILE: src/main/java/org/springframework/data/keyvalue/repository/KeyValueRepository.java
  type KeyValueRepository (line 26) | public interface KeyValueRepository<T, ID> extends ListCrudRepository<T,...

FILE: src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java
  class KeyValueRepositoryConfigurationExtension (line 48) | public abstract class KeyValueRepositoryConfigurationExtension extends R...
    method getRepositoryFactoryBeanClassName (line 53) | @Override
    method getModuleName (line 58) | @Override
    method getModulePrefix (line 63) | @Override
    method getIdentifyingTypes (line 68) | @Override
    method postProcess (line 73) | @Override
    method getQueryCreatorType (line 91) | private static Class<?> getQueryCreatorType(AnnotationRepositoryConfig...
    method getQueryType (line 111) | private static Class<?> getQueryType(AnnotationRepositoryConfiguration...
    method registerBeansForRoot (line 126) | @Override
    method getDefaultKeyValueTemplateBeanDefinition (line 161) | protected @Nullable AbstractBeanDefinition getDefaultKeyValueTemplateB...
    method getDefaultKeyValueTemplateRef (line 175) | protected abstract String getDefaultKeyValueTemplateRef();
    method getMappingContextBeanRef (line 185) | protected String getMappingContextBeanRef() {

FILE: src/main/java/org/springframework/data/keyvalue/repository/query/CachingKeyValuePartTreeQuery.java
  class CachingKeyValuePartTreeQuery (line 34) | public class CachingKeyValuePartTreeQuery extends KeyValuePartTreeQuery {
    method CachingKeyValuePartTreeQuery (line 38) | public CachingKeyValuePartTreeQuery(QueryMethod queryMethod,
    method prepareQuery (line 44) | protected KeyValueQuery<?> prepareQuery(Object[] parameters) {

FILE: src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java
  class KeyValuePartTreeQuery (line 53) | public class KeyValuePartTreeQuery implements RepositoryQuery {
    method KeyValuePartTreeQuery (line 71) | public KeyValuePartTreeQuery(QueryMethod queryMethod, ValueExpressionD...
    method KeyValuePartTreeQuery (line 89) | public KeyValuePartTreeQuery(QueryMethod queryMethod, ValueExpressionD...
    method execute (line 107) | @Override
    method doExecute (line 121) | @SuppressWarnings({ "unchecked", "rawtypes" })
    method prepareQuery (line 149) | protected KeyValueQuery<?> prepareQuery(Object[] parameters) {
    method prepareQuery (line 155) | @SuppressWarnings({ "rawtypes", "unchecked" })
    method getSpelExpression (line 187) | private SpelExpression getSpelExpression(Object criteria) {
    method createQuery (line 206) | @SuppressWarnings("NullAway")
    method getQueryMethod (line 221) | @Override
    type QueryCreatorFactory (line 233) | public interface QueryCreatorFactory<T extends AbstractQueryCreator<?,...
      method queryCreatorFor (line 235) | T queryCreatorFor(PartTree partTree, ParameterAccessor accessor);
    class ConstructorCachingQueryCreatorFactory (line 245) | private static class ConstructorCachingQueryCreatorFactory
      method ConstructorCachingQueryCreatorFactory (line 251) | ConstructorCachingQueryCreatorFactory(Class<? extends AbstractQueryC...
      method queryCreatorFor (line 257) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/repository/query/PredicateQueryCreator.java
  class PredicateQueryCreator (line 50) | public class PredicateQueryCreator extends AbstractQueryCreator<KeyValue...
    method PredicateQueryCreator (line 54) | public PredicateQueryCreator(PartTree tree, ParameterAccessor paramete...
    method create (line 58) | @Override
    method and (line 87) | @Override
    method or (line 93) | @Override
    method complete (line 99) | @Override
    class PredicateBuilder (line 104) | static class PredicateBuilder {
      method PredicateBuilder (line 108) | public PredicateBuilder(Part part) {
      method comparator (line 112) | @SuppressWarnings("unchecked")
      method propertyValueOf (line 117) | static PredicateBuilder propertyValueOf(Part part) {
      method isTrue (line 121) | public Predicate<Object> isTrue() {
      method isFalse (line 125) | public Predicate<Object> isFalse() {
      method isEqualTo (line 129) | @Contract("_ -> new")
      method isNull (line 143) | public Predicate<Object> isNull() {
      method isNotNull (line 147) | public Predicate<Object> isNotNull() {
      method isLessThan (line 151) | @Contract("_ -> new")
      method isLessThanEqual (line 156) | @Contract("_ -> new")
      method isGreaterThan (line 161) | @Contract("_ -> new")
      method isGreaterThanEqual (line 166) | @Contract("_ -> new")
      method matches (line 171) | @Contract("!null -> new")
      method matches (line 183) | @Contract("_ -> new")
      method matches (line 200) | @Contract("!null -> new")
      method in (line 205) | @Contract("!null -> new")
      method contains (line 224) | @Contract("_ -> new")
      method startsWith (line 259) | @Contract("!null -> new")
      method endsWith (line 276) | @Contract("!null -> new")
    class ValueComparingPredicate (line 294) | static class ValueComparingPredicate implements Predicate<Object> {
      method ValueComparingPredicate (line 299) | public ValueComparingPredicate(PropertyPath path, @Nullable Object e...
      method ValueComparingPredicate (line 303) | public ValueComparingPredicate(PropertyPath path, Function<@Nullable...
      method test (line 308) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreator.java
  class SpelQueryCreator (line 43) | public class SpelQueryCreator extends AbstractQueryCreator<KeyValueQuery...
    method SpelQueryCreator (line 55) | public SpelQueryCreator(PartTree tree, ParameterAccessor parameters) {
    method create (line 62) | @Override
    method and (line 67) | @Override
    method or (line 72) | @Override
    method complete (line 77) | @Override
    method toPredicateExpression (line 89) | protected SpelExpression toPredicateExpression(PartTree tree) {
    method requiresInverseLookup (line 229) | private static boolean requiresInverseLookup(Part part) {

FILE: src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueQuerydslUtils.java
  class KeyValueQuerydslUtils (line 43) | abstract class KeyValueQuerydslUtils {
    method KeyValueQuerydslUtils (line 45) | private KeyValueQuerydslUtils() {
    method toOrderSpecifier (line 56) | @Contract("!null, !null -> new")
    method toOrderSpecifier (line 77) | @SuppressWarnings({ "rawtypes", "unchecked" })
    method buildOrderPropertyPathFrom (line 91) | private static Expression<?> buildOrderPropertyPathFrom(Order order, P...
    method toQueryDslNullHandling (line 121) | private static NullHandling toQueryDslNullHandling(org.springframework...

FILE: src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactory.java
  class KeyValueRepositoryFactory (line 59) | public class KeyValueRepositoryFactory extends RepositoryFactorySupport {
    method KeyValueRepositoryFactory (line 73) | public KeyValueRepositoryFactory(KeyValueOperations keyValueOperations) {
    method KeyValueRepositoryFactory (line 84) | public KeyValueRepositoryFactory(KeyValueOperations keyValueOperations,
    method KeyValueRepositoryFactory (line 99) | public KeyValueRepositoryFactory(KeyValueOperations keyValueOperations,
    method getEntityInformation (line 112) | @Override
    method getTargetRepository (line 121) | @Override
    method getRepositoryBaseClass (line 128) | @Override
    method getRepositoryFragments (line 133) | @Override
    method getRepositoryFragments (line 149) | protected RepositoryFragments getRepositoryFragments(RepositoryMetadat...
    method isQueryDslRepository (line 172) | private static boolean isQueryDslRepository(Class<?> repositoryInterfa...
    method getQueryLookupStrategy (line 176) | @Override
    class KeyValueQueryLookupStrategy (line 187) | private static class KeyValueQueryLookupStrategy implements QueryLooku...
      method KeyValueQueryLookupStrategy (line 202) | public KeyValueQueryLookupStrategy(@Nullable Key key, ValueExpressio...
      method resolveQuery (line 217) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactoryBean.java
  class KeyValueRepositoryFactoryBean (line 37) | public class KeyValueRepositoryFactoryBean<T extends Repository<S, ID>, ...
    method KeyValueRepositoryFactoryBean (line 49) | public KeyValueRepositoryFactoryBean(Class<? extends T> repositoryInte...
    method setKeyValueOperations (line 58) | public void setKeyValueOperations(KeyValueOperations operations) {
    method setMappingContext (line 65) | @Override
    method setQueryCreator (line 75) | public void setQueryCreator(Class<? extends AbstractQueryCreator<?, ?>...
    method setQueryType (line 88) | public void setQueryType(Class<? extends RepositoryQuery> repositoryQu...
    method createRepositoryFactory (line 96) | @Override
    method createRepositoryFactory (line 115) | protected KeyValueRepositoryFactory createRepositoryFactory(KeyValueOp...
    method afterPropertiesSet (line 121) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/repository/support/QuerydslKeyValuePredicateExecutor.java
  class QuerydslKeyValuePredicateExecutor (line 66) | public class QuerydslKeyValuePredicateExecutor<T> implements ListQueryds...
    method QuerydslKeyValuePredicateExecutor (line 83) | public QuerydslKeyValuePredicateExecutor(EntityInformation<T, ?> entit...
    method QuerydslKeyValuePredicateExecutor (line 96) | public QuerydslKeyValuePredicateExecutor(EntityInformation<T, ?> entit...
    method findOne (line 113) | @Override
    method findAll (line 125) | @Override
    method findAll (line 133) | @Override
    method findAll (line 145) | @Override
    method findAll (line 154) | @Override
    method findAll (line 175) | @Override
    method count (line 190) | @Override
    method exists (line 198) | @Override
    method findBy (line 206) | @Override
    method prepareQuery (line 223) | protected AbstractCollQuery<T, ?> prepareQuery(@Nullable Predicate pre...
    class FluentQuerydsl (line 238) | class FluentQuerydsl<R> implements FluentQuery.FetchableFluentQuery<R> {
      method FluentQuerydsl (line 246) | FluentQuerydsl(Predicate predicate, Class<R> resultType) {
      method FluentQuerydsl (line 250) | public FluentQuerydsl(Predicate predicate, Sort sort, Class<?> entit...
      method sortBy (line 259) | @Override
      method as (line 267) | @Override
      method project (line 275) | public FluentQuery.FetchableFluentQuery<R> project(Collection<String...
      method oneValue (line 282) | @Override
      method firstValue (line 300) | @Override
      method all (line 313) | @Override
      method page (line 321) | @Override
      method stream (line 342) | @Override
      method count (line 347) | @Override
      method exists (line 352) | @Override
      method createQuery (line 357) | private AbstractCollQuery<T, ?> createQuery() {
      method mapResults (line 367) | @SuppressWarnings("unchecked")
      method getConversionFunction (line 384) | @SuppressWarnings("unchecked")
      method getConversionFunction (line 400) | private Function<Object, R> getConversionFunction() {

FILE: src/main/java/org/springframework/data/keyvalue/repository/support/QuerydslKeyValueRepository.java
  class QuerydslKeyValueRepository (line 49) | @Deprecated
    method QuerydslKeyValueRepository (line 62) | public QuerydslKeyValueRepository(EntityInformation<T, ID> entityInfor...
    method QuerydslKeyValueRepository (line 74) | public QuerydslKeyValueRepository(EntityInformation<T, ID> entityInfor...
    method findOne (line 85) | @Override
    method findAll (line 90) | @Override
    method findAll (line 95) | @Override
    method findAll (line 100) | @Override
    method findAll (line 105) | @Override
    method findAll (line 110) | @Override
    method count (line 115) | @Override
    method exists (line 120) | @Override
    method findBy (line 125) | @Override

FILE: src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java
  class SimpleKeyValueRepository (line 42) | public class SimpleKeyValueRepository<T, ID> implements KeyValueReposito...
    method SimpleKeyValueRepository (line 54) | public SimpleKeyValueRepository(EntityInformation<T, ID> metadata, Key...
    method save (line 67) | @Override
    method saveAll (line 79) | @Override
    method findById (line 93) | @Override
    method existsById (line 101) | @Override
    method findAll (line 106) | @Override
    method findAllById (line 111) | @Override
    method count (line 123) | @Override
    method deleteById (line 128) | @Override
    method delete (line 136) | @Override
    method deleteAllById (line 144) | @Override
    method deleteAll (line 152) | @Override
    method deleteAll (line 160) | @Override
    method findAll (line 169) | @Override
    method findAll (line 177) | @Override

FILE: src/main/java/org/springframework/data/map/KeySpaceStore.java
  type KeySpaceStore (line 47) | public interface KeySpaceStore {
    method getKeySpace (line 57) | Map<Object, Object> getKeySpace(String keyspace);
    method clear (line 63) | void clear();
    method create (line 70) | static KeySpaceStore create() {
    method of (line 80) | @SuppressWarnings("rawtypes")
    method of (line 91) | static KeySpaceStore of(Map<String, Map<Object, Object>> store) {

FILE: src/main/java/org/springframework/data/map/MapKeySpaceStore.java
  method create (line 45) | public static KeySpaceStore create() {
  method of (line 55) | public static KeySpaceStore of(Class<? extends Map> mapType) {
  method of (line 68) | @SuppressWarnings("unchecked")
  method getKeySpace (line 77) | @Override
  method clear (line 82) | @Override

FILE: src/main/java/org/springframework/data/map/MapKeyValueAdapter.java
  class MapKeyValueAdapter (line 42) | public class MapKeyValueAdapter extends AbstractKeyValueAdapter {
    method MapKeyValueAdapter (line 49) | public MapKeyValueAdapter() {
    method MapKeyValueAdapter (line 59) | public MapKeyValueAdapter(QueryEngine<? extends KeyValueAdapter, ?, ?>...
    method MapKeyValueAdapter (line 68) | @SuppressWarnings("rawtypes")
    method MapKeyValueAdapter (line 80) | @SuppressWarnings("rawtypes")
    method MapKeyValueAdapter (line 92) | @SuppressWarnings("rawtypes")
    method MapKeyValueAdapter (line 102) | public MapKeyValueAdapter(Map<String, Map<Object, Object>> store) {
    method MapKeyValueAdapter (line 113) | public MapKeyValueAdapter(Map<String, Map<Object, Object>> store, Quer...
    method MapKeyValueAdapter (line 122) | public MapKeyValueAdapter(KeySpaceStore store) {
    method MapKeyValueAdapter (line 133) | public MapKeyValueAdapter(KeySpaceStore store, @Nullable QueryEngine<?...
    method put (line 141) | @Override
    method contains (line 150) | @Override
    method count (line 155) | @Override
    method get (line 160) | @Override
    method delete (line 167) | @Override
    method getAllOf (line 174) | @Override
    method entries (line 179) | @Override
    method deleteAllOf (line 184) | @Override
    method clear (line 189) | @Override
    method destroy (line 194) | @Override
    method getKeySpaceMap (line 205) | protected Map<Object, Object> getKeySpaceMap(String keyspace) {

FILE: src/main/java/org/springframework/data/map/repository/config/MapRepositoriesRegistrar.java
  class MapRepositoriesRegistrar (line 28) | public class MapRepositoriesRegistrar extends RepositoryBeanDefinitionRe...
    method getAnnotation (line 30) | @Override
    method getExtension (line 35) | @Override

FILE: src/main/java/org/springframework/data/map/repository/config/MapRepositoryConfigurationExtension.java
  class MapRepositoryConfigurationExtension (line 47) | @SuppressWarnings("unchecked")
    method getModuleName (line 50) | @Override
    method getModulePrefix (line 55) | @Override
    method getDefaultKeyValueTemplateRef (line 60) | @Override
    method getDefaultKeyValueTemplateBeanDefinition (line 65) | @Override
    method getKeySpaceStore (line 89) | private static Object getKeySpaceStore(RepositoryConfigurationSource s...
    method getSortAccessor (line 98) | private static @Nullable SortAccessor<?> getSortAccessor(RepositoryCon...
    method getQueryEngine (line 109) | private static @Nullable QueryEngine<?, ?, ?> getQueryEngine(@Nullable...
    method getClassAttribute (line 129) | private static <T> @Nullable Class<T> getClassAttribute(RepositoryConf...

FILE: src/test/java/org/springframework/data/keyvalue/Person.java
  class Person (line 28) | @QueryEntity
    method Person (line 36) | public Person(String firstname, int age) {
    method getId (line 42) | public String getId() {
    method getFirstname (line 46) | public String getFirstname() {
    method getAge (line 50) | public int getAge() {
    method setId (line 54) | public void setId(String id) {
    method setFirstname (line 58) | public void setFirstname(String firstname) {
    method setAge (line 62) | public void setAge(int age) {
    method getHomepage (line 66) | public URL getHomepage() {
    method setHomepage (line 70) | public void setHomepage(URL homepage) {

FILE: src/test/java/org/springframework/data/keyvalue/SubclassOfTypeWithCustomComposedKeySpaceAnnotation.java
  class SubclassOfTypeWithCustomComposedKeySpaceAnnotation (line 26) | public class SubclassOfTypeWithCustomComposedKeySpaceAnnotation
    method SubclassOfTypeWithCustomComposedKeySpaceAnnotation (line 29) | public SubclassOfTypeWithCustomComposedKeySpaceAnnotation(String name) {

FILE: src/test/java/org/springframework/data/keyvalue/TypeWithCustomComposedKeySpaceAnnotationUsingAliasFor.java
  class TypeWithCustomComposedKeySpaceAnnotationUsingAliasFor (line 27) | @CustomKeySpaceAnnotationWithAliasFor(name = "aliased")
    method TypeWithCustomComposedKeySpaceAnnotationUsingAliasFor (line 33) | public TypeWithCustomComposedKeySpaceAnnotationUsingAliasFor(String na...
    method getId (line 37) | public String getId() {
    method getName (line 41) | public String getName() {
    method setId (line 45) | public void setId(String id) {
    method setName (line 49) | public void setName(String name) {

FILE: src/test/java/org/springframework/data/keyvalue/TypeWithDirectKeySpaceAnnotation.java
  class TypeWithDirectKeySpaceAnnotation (line 26) | @KeySpace("rhaegar")

FILE: src/test/java/org/springframework/data/keyvalue/TypeWithInhteritedPersistentAnnotationNotHavingKeySpace.java
  class TypeWithInhteritedPersistentAnnotationNotHavingKeySpace (line 27) | @TypeAlias("foo")

FILE: src/test/java/org/springframework/data/keyvalue/TypeWithPersistentAnnotationNotHavingKeySpace.java
  class TypeWithPersistentAnnotationNotHavingKeySpace (line 26) | @Persistent

FILE: src/test/java/org/springframework/data/keyvalue/core/DefaultIdentifierGeneratorUnitTests.java
  class DefaultIdentifierGeneratorUnitTests (line 30) | class DefaultIdentifierGeneratorUnitTests {
    method shouldThrowExceptionForUnsupportedType (line 34) | @Test
    method shouldGenerateUUIDValueCorrectly (line 40) | @Test // DATAKV-136
    method shouldGenerateStringValueCorrectly (line 48) | @Test // DATAKV-136
    method shouldGenerateLongValueCorrectly (line 56) | @Test // DATAKV-136
    method shouldGenerateIntValueCorrectly (line 64) | @Test // DATAKV-136

FILE: src/test/java/org/springframework/data/keyvalue/core/ForwardingCloseableIteratorUnitTests.java
  class ForwardingCloseableIteratorUnitTests (line 38) | @ExtendWith(MockitoExtension.class)
    method hasNextShouldDelegateToWrappedIterator (line 44) | @Test // DATAKV-99
    method nextShouldDelegateToWrappedIterator (line 59) | @Test // DATAKV-99
    method nextShouldThrowErrorWhenWrappedIteratorHasNoMoreElements (line 75) | @Test // DATAKV-99
    method closeShouldDoNothingByDefault (line 89) | @Test // DATAKV-99
    method closeShouldInvokeConfiguredCloseAction (line 97) | @Test // DATAKV-99

FILE: src/test/java/org/springframework/data/keyvalue/core/IterableConverterUnitTests.java
  class IterableConverterUnitTests (line 34) | class IterableConverterUnitTests {
    method toListShouldReturnEmptyListWhenSourceEmpty (line 36) | @Test // DATAKV-101
    method toListShouldReturnSameObjectWhenSourceIsAlreadyListType (line 41) | @Test // DATAKV-101
    method toListShouldReturnListWhenSourceIsNonListType (line 49) | @Test // DATAKV-101
    method toListShouldHoldValuesInOrderOfSource (line 58) | @Test // DATAKV-101

FILE: src/test/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslatorUnitTests.java
  class KeyValuePersistenceExceptionTranslatorUnitTests (line 30) | class KeyValuePersistenceExceptionTranslatorUnitTests {
    method translateExeptionShouldReturnDataAccessExceptionWhenGivenOne (line 34) | @Test // DATACMNS-525
    method translateExeptionShouldReturnNullWhenGivenNull (line 40) | @Test // DATACMNS-525, DATAKV-192
    method translateExeptionShouldTranslateNoSuchElementExceptionToDataRetrievalFailureException (line 46) | @Test // DATACMNS-525
    method translateExeptionShouldTranslateIndexOutOfBoundsExceptionToDataRetrievalFailureException (line 52) | @Test // DATACMNS-525
    method translateExeptionShouldTranslateIllegalStateExceptionToDataRetrievalFailureException (line 58) | @Test // DATACMNS-525
    method translateExeptionShouldTranslateAnyJavaExceptionToUncategorizedKeyValueException (line 64) | @Test // DATACMNS-525
    method translateExeptionShouldReturnNullForNonJavaExceptions (line 70) | @Test // DATACMNS-525

FILE: src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateTests.java
  class KeyValueTemplateTests (line 44) | class KeyValueTemplateTests {
    method setUp (line 57) | @BeforeEach
    method tearDown (line 62) | @AfterEach
    method insertShouldNotThorwErrorWhenExecutedHavingNonExistingIdAndNonNullValue (line 67) | @Test // DATACMNS-525
    method insertShouldThrowExceptionForNullId (line 72) | @Test // DATACMNS-525
    method insertShouldThrowExceptionForNullObject (line 77) | @Test // DATACMNS-525
    method insertShouldThrowExecptionWhenObjectOfSameTypeAlreadyExists (line 82) | @Test // DATACMNS-525
    method insertShouldWorkCorrectlyWhenObjectsOfDifferentTypesWithSameIdAreInserted (line 90) | @Test // DATACMNS-525
    method createShouldReturnSameInstanceGenerateId (line 97) | @Test // DATACMNS-525
    method createShouldRespectExistingId (line 106) | @Test // DATACMNS-525
    method findByIdShouldReturnObjectWithMatchingIdAndType (line 117) | @Test // DATACMNS-525
    method findByIdSouldReturnOptionalEmptyIfNoMatchingIdFound (line 124) | @Test // DATACMNS-525
    method findByIdShouldReturnOptionalEmptyIfNoMatchingTypeFound (line 131) | @Test // DATACMNS-525
    method findShouldExecuteQueryCorrectly (line 138) | @Test // DATACMNS-525
    method readShouldReturnEmptyCollectionIfOffsetOutOfRange (line 149) | @Test // DATACMNS-525
    method updateShouldReplaceExistingObject (line 159) | @Test // DATACMNS-525
    method updateShouldRespectTypeInformation (line 167) | @Test // DATACMNS-525
    method deleteShouldRemoveObjectCorrectly (line 176) | @Test // DATACMNS-525
    method deleteReturnsNullWhenNotExisting (line 184) | @Test // DATACMNS-525
    method deleteReturnsRemovedObject (line 191) | @Test // DATACMNS-525
    method deleteThrowsExceptionWhenIdCannotBeExctracted (line 198) | @Test // DATACMNS-525
    method countShouldReturnZeroWhenNoElementsPresent (line 203) | @Test // DATACMNS-525
    method insertShouldRespectTypeAlias (line 208) | @Test // DATACMNS-525
    class Foo (line 217) | static class Foo {
      method Foo (line 221) | public Foo(String foo) {
      method getFoo (line 225) | public String getFoo() {
      method setFoo (line 229) | public void setFoo(String foo) {
    class Bar (line 234) | static class Bar {
      method Bar (line 238) | public Bar(String bar) {
      method getBar (line 242) | public String getBar() {
      method setBar (line 246) | public void setBar(String bar) {
    class ClassWithStringId (line 251) | static class ClassWithStringId implements Serializable {
      method getId (line 257) | public String getId() {
      method setId (line 261) | public void setId(String id) {
      method getValue (line 265) | public String getValue() {
      method setValue (line 269) | public void setValue(String value) {
    class ClassWithTypeAlias (line 274) | @ExplicitKeySpace(name = "aliased")
      method ClassWithTypeAlias (line 281) | ClassWithTypeAlias(String name) {
      method getId (line 285) | public String getId() {
      method getName (line 289) | public String getName() {
      method setId (line 293) | public void setId(String id) {
      method setName (line 297) | public void setName(String name) {
    class SubclassOfAliasedType (line 302) | static class SubclassOfAliasedType extends ClassWithTypeAlias {
      method SubclassOfAliasedType (line 306) | SubclassOfAliasedType(String name) {

FILE: src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java
  class KeyValueTemplateUnitTests (line 58) | @ExtendWith(MockitoExtension.class)
    method setUp (line 74) | @BeforeEach
    method shouldThrowExceptionWhenCreatingNewTempateWithNullAdapter (line 80) | @Test // DATACMNS-525
    method shouldThrowExceptionWhenCreatingNewTempateWithNullMappingContext (line 85) | @Test // DATACMNS-525
    method insertShouldLookUpValuesBeforeInserting (line 90) | @Test // DATACMNS-525
    method insertShouldInsertUseClassNameAsDefaultKeyspace (line 98) | @Test // DATACMNS-525
    method insertShouldReturnInsertedObject (line 106) | @Test // DATACMNS-225
    method insertShouldThrowExceptionWhenObectWithIdAlreadyExists (line 115) | @Test // DATACMNS-525
    method insertShouldThrowExceptionForNullId (line 123) | @Test // DATACMNS-525
    method insertShouldThrowExceptionForNullObject (line 128) | @Test // DATACMNS-525
    method insertShouldGenerateId (line 133) | @Test // DATACMNS-525
    method insertShouldThrowErrorWhenIdCannotBeResolved (line 141) | @Test // DATACMNS-525
    method insertShouldReturnSameInstanceGenerateId (line 146) | @Test // DATACMNS-525
    method insertShouldRespectExistingId (line 155) | @Test // DATACMNS-525
    method findByIdShouldReturnOptionalEmptyWhenNoElementsPresent (line 166) | @Test // DATACMNS-525
    method findByIdShouldReturnObjectWithMatchingIdAndType (line 171) | @Test // DATACMNS-525
    method findByIdShouldThrowExceptionWhenGivenNullId (line 179) | @Test // DATACMNS-525, DATAKV-187
    method findAllOfShouldReturnEntireCollection (line 184) | @Test // DATACMNS-525
    method findAllOfShouldThrowExceptionWhenGivenNullType (line 192) | @Test // DATACMNS-525
    method findShouldCallFindOnAdapterToResolveMatching (line 197) | @Test // DATACMNS-525
    method findInRangeShouldRespectOffset (line 205) | @Test // DATACMNS-525
    method updateShouldReplaceExistingObject (line 219) | @Test // DATACMNS-525
    method updateShouldReturnUpdatedObject (line 227) | @Test // DATAKV-225
    method updateShouldThrowExceptionWhenGivenNullId (line 237) | @Test // DATACMNS-525
    method updateShouldThrowExceptionWhenGivenNullObject (line 242) | @Test // DATACMNS-525
    method updateShouldUseExtractedIdInformation (line 247) | @Test // DATACMNS-525
    method updateShouldThrowErrorWhenIdInformationCannotBeExtracted (line 258) | @Test // DATACMNS-525
    method deleteShouldRemoveObjectCorrectly (line 263) | @Test // DATACMNS-525
    method deleteRemovesObjectUsingExtractedId (line 271) | @Test // DATACMNS-525
    method deleteThrowsExceptionWhenIdCannotBeExctracted (line 282) | @Test // DATACMNS-525
    method countShouldReturnZeroWhenNoElementsPresent (line 287) | @Test // DATACMNS-525
    method countShouldReturnCollectionSize (line 292) | @Test // DATACMNS-525
    method countShouldThrowErrorOnNullType (line 300) | @Test // DATACMNS-525
    method insertShouldRespectTypeAlias (line 305) | @Test // DATACMNS-525
    method insertShouldRespectTypeAliasOnSubClass (line 313) | @Test // DATACMNS-525
    method findAllOfShouldRespectTypeAliasAndFilterNonMatchingTypes (line 321) | @SuppressWarnings({ "rawtypes", "unchecked" })
    method insertSouldRespectTypeAliasAndFilterNonMatching (line 332) | @Test // DATACMNS-525
    method setttingNullPersistenceExceptionTranslatorShouldThrowException (line 339) | @Test // DATACMNS-525
    method shouldNotPublishEventWhenNoApplicationContextSet (line 344) | @Test // DATAKV-91
    method shouldNotPublishEventsWhenEventsToPublishIsSetToNull (line 354) | @Test // DATAKV-104
    method shouldNotPublishEventsWhenEventsToPublishIsSetToEmptyList (line 364) | @Test // DATAKV-104
    method shouldPublishEventsByDefault (line 375) | @Test // DATAKV-104
    method shouldNotPublishEventWhenNotExplicitlySetForPublication (line 383) | @Test // DATAKV-91, DATAKV-104
    method shouldPublishBeforeInsertEventCorrectly (line 394) | @Test // DATAKV-91, DATAKV-104, DATAKV-187
    method shouldPublishAfterInsertEventCorrectly (line 412) | @Test // DATAKV-91, DATAKV-104, DATAKV-187
    method shouldPublishBeforeUpdateEventCorrectly (line 430) | @Test // DATAKV-91, DATAKV-104, DATAKV-187
    method shouldPublishAfterUpdateEventCorrectly (line 448) | @Test // DATAKV-91, DATAKV-104, DATAKV-187
    method shouldPublishBeforeDeleteEventCorrectly (line 466) | @Test // DATAKV-91, DATAKV-104, DATAKV-187
    method shouldPublishAfterDeleteEventCorrectly (line 483) | @Test // DATAKV-91, DATAKV-104, DATAKV-187
    method shouldPublishBeforeGetEventCorrectly (line 502) | @Test // DATAKV-91, DATAKV-104, DATAKV-187
    method shouldPublishAfterGetEventCorrectly (line 521) | @Test // DATAKV-91, DATAKV-104
    method shouldPublishDropKeyspaceEventCorrectly (line 541) | @Test // DATAKV-91, DATAKV-104, DATAKV-187
    method insertShouldRespectTypeAliasUsingAliasFor (line 557) | @Test // DATAKV-129
    method setEventsToPublish (line 565) | @SafeVarargs
    class Foo (line 571) | static class Foo {
      method Foo (line 575) | public Foo(String foo) {
      method getFoo (line 579) | public String getFoo() {
      method setFoo (line 583) | public void setFoo(String foo) {
    class Bar (line 588) | class Bar {
      method Bar (line 592) | public Bar(String bar) {
      method getBar (line 596) | public String getBar() {
      method setBar (line 600) | public void setBar(String bar) {
    class ClassWithStringId (line 605) | static class ClassWithStringId {
      method getId (line 610) | public String getId() {
      method getValue (line 614) | public String getValue() {
      method setId (line 618) | public void setId(String id) {
      method setValue (line 622) | public void setValue(String value) {

FILE: src/test/java/org/springframework/data/keyvalue/core/PredicateQueryEngineUnitTests.java
  class PredicateQueryEngineUnitTests (line 48) | @ExtendWith(MockitoExtension.class)
    method setUp (line 60) | @BeforeEach
    method queriesEntitiesWithNullProperty (line 67) | @Test // DATAKV-114
    method countsEntitiesWithNullProperty (line 78) | @Test // DATAKV-114
    method createQueryForMethodWithArgs (line 86) | private static Predicate<?> createQueryForMethodWithArgs(String method...
    type PersonRepository (line 107) | interface PersonRepository {
      method findByFirstname (line 108) | Person findByFirstname(String firstname);
    class Person (line 111) | public static class Person {
      method Person (line 117) | Person(String firstname, int age) {
      method getFirstname (line 123) | public String getFirstname() {

FILE: src/test/java/org/springframework/data/keyvalue/core/PropertyPathComparatorUnitTests.java
  class PropertyPathComparatorUnitTests (line 29) | class PropertyPathComparatorUnitTests {
    method shouldCompareStringAscCorrectly (line 36) | @Test // DATACMNS-525
    method shouldCompareStringDescCorrectly (line 43) | @Test // DATACMNS-525
    method shouldCompareIntegerAscCorrectly (line 50) | @Test // DATACMNS-525
    method shouldCompareIntegerDescCorrectly (line 57) | @Test // DATACMNS-525
    method shouldComparePrimitiveIntegerAscCorrectly (line 64) | @Test // DATACMNS-525
    method shouldNotFailOnNullValues (line 72) | @Test // DATACMNS-525
    method shouldComparePrimitiveIntegerDescCorrectly (line 79) | @Test // DATACMNS-525
    method shouldSortNullsFirstCorrectly (line 87) | @Test // DATACMNS-525
    method shouldSortNullsLastCorrectly (line 93) | @Test // DATACMNS-525
    method shouldCompareNestedTypesCorrectly (line 100) | @Test // DATACMNS-525
    method shouldCompareNestedTypesCorrectlyWhenOneOfThemHasNullValue (line 108) | @Test // DATACMNS-525
    class WrapperType (line 115) | public static class WrapperType {
      method WrapperType (line 120) | WrapperType(String stringPropertyWrapper, SomeType nestedType) {
      method getStringPropertyWrapper (line 125) | public String getStringPropertyWrapper() {
      method setStringPropertyWrapper (line 129) | public void setStringPropertyWrapper(String stringPropertyWrapper) {
      method getNestedType (line 133) | public SomeType getNestedType() {
      method setNestedType (line 137) | public void setNestedType(SomeType nestedType) {
    class SomeType (line 143) | @SuppressWarnings("WeakerAccess")
      method SomeType (line 146) | public SomeType() {
      method SomeType (line 150) | SomeType(String stringProperty, Integer integerProperty, int primiti...
      method getStringProperty (line 160) | public String getStringProperty() {
      method setStringProperty (line 164) | public void setStringProperty(String stringProperty) {
      method getIntegerProperty (line 168) | public Integer getIntegerProperty() {
      method setIntegerProperty (line 172) | public void setIntegerProperty(Integer integerProperty) {
      method getPrimitiveProperty (line 176) | public int getPrimitiveProperty() {
      method setPrimitiveProperty (line 180) | public void setPrimitiveProperty(int primitiveProperty) {

FILE: src/test/java/org/springframework/data/keyvalue/core/SpelPropertyComparatorUnitTests.java
  class SpelPropertyComparatorUnitTests (line 33) | class SpelPropertyComparatorUnitTests {
    method shouldCompareStringAscCorrectly (line 42) | @Test // DATACMNS-525
    method shouldCompareStringDescCorrectly (line 49) | @Test // DATACMNS-525
    method shouldCompareIntegerAscCorrectly (line 56) | @Test // DATACMNS-525
    method shouldCompareIntegerDescCorrectly (line 63) | @Test // DATACMNS-525
    method shouldComparePrimitiveIntegerAscCorrectly (line 70) | @Test // DATACMNS-525
    method shouldNotFailOnNullValues (line 78) | @Test // DATACMNS-525
    method shouldComparePrimitiveIntegerDescCorrectly (line 85) | @Test // DATACMNS-525
    method shouldSortNullsFirstCorrectly (line 93) | @Test // DATACMNS-525
    method shouldSortNullsLastCorrectly (line 99) | @Test // DATACMNS-525
    method shouldCompareNestedTypesCorrectly (line 106) | @Test // DATACMNS-525
    method shouldCompareNestedTypesCorrectlyWhenOneOfThemHasNullValue (line 114) | @Test // DATACMNS-525
    class WrapperType (line 121) | public static class WrapperType {
      method WrapperType (line 126) | WrapperType(String stringPropertyWrapper, SomeType nestedType) {
      method getStringPropertyWrapper (line 131) | public String getStringPropertyWrapper() {
      method setStringPropertyWrapper (line 135) | public void setStringPropertyWrapper(String stringPropertyWrapper) {
      method getNestedType (line 139) | public SomeType getNestedType() {
      method setNestedType (line 143) | public void setNestedType(SomeType nestedType) {
    class SomeType (line 149) | @SuppressWarnings("WeakerAccess")
      method SomeType (line 152) | public SomeType() {
      method SomeType (line 156) | SomeType(String stringProperty, Integer integerProperty, int primiti...
      method getStringProperty (line 166) | public String getStringProperty() {
      method setStringProperty (line 170) | public void setStringProperty(String stringProperty) {
      method getIntegerProperty (line 174) | public Integer getIntegerProperty() {
      method setIntegerProperty (line 178) | public void setIntegerProperty(Integer integerProperty) {
      method getPrimitiveProperty (line 182) | public int getPrimitiveProperty() {
      method setPrimitiveProperty (line 186) | public void setPrimitiveProperty(int primitiveProperty) {

FILE: src/test/java/org/springframework/data/keyvalue/core/SpelQueryEngineUnitTests.java
  class SpelQueryEngineUnitTests (line 50) | @ExtendWith(MockitoExtension.class)
    method setUp (line 62) | @BeforeEach
    method queriesEntitiesWithNullProperty (line 69) | @Test // DATAKV-114
    method countsEntitiesWithNullProperty (line 80) | @Test // DATAKV-114
    method createQueryForMethodWithArgs (line 88) | private static SpelCriteria createQueryForMethodWithArgs(String method...
    type PersonRepository (line 110) | interface PersonRepository {
      method findByFirstname (line 111) | Person findByFirstname(String firstname);
    class Person (line 114) | public static class Person {
      method Person (line 120) | Person(String firstname, int age) {
      method getFirstname (line 126) | public String getFirstname() {

FILE: src/test/java/org/springframework/data/keyvalue/core/mapping/AnnotationBasedKeySpaceResolverUnitTests.java
  class AnnotationBasedKeySpaceResolverUnitTests (line 41) | class AnnotationBasedKeySpaceResolverUnitTests {
    method setUp (line 45) | @BeforeEach
    method shouldResolveKeySpaceDefaultValueCorrectly (line 50) | @Test // DATACMNS-525
    method shouldReturnNullWhenNoKeySpaceFoundOnComposedPersistentAnnotation (line 55) | @Test // DATAKV-105
    method shouldReturnNullWhenPersistentIsFoundOnNonComposedAnnotation (line 60) | @Test // DATAKV-105
    method shouldReturnNullWhenPersistentIsNotFound (line 65) | @Test // DATAKV-105
    method shouldResolveInheritedKeySpaceCorrectly (line 70) | @Test // DATACMNS-525
    method shouldResolveDirectKeySpaceAnnotationCorrectly (line 75) | @Test // DATACMNS-525
    method shouldResolveKeySpaceUsingAliasForCorrectly (line 80) | @Test // DATAKV-129
    method shouldResolveKeySpaceUsingAliasForCorrectlyOnSubClass (line 85) | @Test // DATAKV-129
    class EntityWithDefaultKeySpace (line 90) | @PersistentAnnotationWithExplicitKeySpaceUsingAliasFor
    class EntityWithSetKeySpaceUsingAliasFor (line 95) | @PersistentAnnotationWithExplicitKeySpaceUsingAliasFor(firstname = "vi...
    class EntityWithInheritedKeySpace (line 100) | private static class EntityWithInheritedKeySpace extends EntityWithSet...
    class EntityWithInheritedKeySpaceUsingAliasFor (line 104) | private static class EntityWithInheritedKeySpaceUsingAliasFor extends ...
    class TypeWithoutKeySpace (line 121) | static class TypeWithoutKeySpace {

FILE: src/test/java/org/springframework/data/keyvalue/core/mapping/BasicKeyValuePersistentEntityUnitTests.java
  class BasicKeyValuePersistentEntityUnitTests (line 36) | class BasicKeyValuePersistentEntityUnitTests {
    method shouldDeriveKeyspaceFromClassName (line 40) | @Test // DATAKV-268
    method shouldEvaluateKeyspaceExpression (line 47) | @Test // DATAKV-268, GH-613
    method shouldEvaluateEntityWithoutKeyspace (line 60) | @Test // DATAKV-268
    method shouldApplyKeySpaceResolver (line 70) | @Test // GH-461
    method shouldFallBackToDefaultsIfKeySpaceResolverReturnsNull (line 79) | @Test // GH-461
    class ExpressionEntity (line 88) | @KeySpace("#{myProperty}_${my.property}")
    class KeyspaceEntity (line 91) | @KeySpace
    class NoKeyspaceEntity (line 94) | private static class NoKeyspaceEntity {}
    class SampleExtension (line 96) | static class SampleExtension implements EvaluationContextExtension {
      method getExtensionId (line 98) | @Override
      method getProperties (line 103) | @Override

FILE: src/test/java/org/springframework/data/keyvalue/core/mapping/PrefixKeyspaceResolverUnitTests.java
  class PrefixKeyspaceResolverUnitTests (line 27) | class PrefixKeyspaceResolverUnitTests {
    method shouldApplyPrefix (line 29) | @Test // gh-461

FILE: src/test/java/org/springframework/data/keyvalue/core/mapping/context/KeyValueMappingContextUnitTests.java
  class KeyValueMappingContextUnitTests (line 34) | class KeyValueMappingContextUnitTests<P extends KeyValuePersistentProper...
    method shouldNotCreateEntitiesForJavaStandardTypes (line 36) | @Test

FILE: src/test/java/org/springframework/data/keyvalue/repository/MapRepositoriesRegistrarUnitTests.java
  class MapRepositoriesRegistrarUnitTests (line 41) | class MapRepositoriesRegistrarUnitTests {
    method setUp (line 45) | @BeforeEach
    method configuresRepositoriesCorrectly (line 50) | @ParameterizedTest // GH-499, GH-3440
    method args (line 63) | static Stream<Arguments> args() {
    class Config (line 71) | @EnableMapRepositories(basePackageClasses = PersonRepository.class, co...
    class ConfigWithBeanNameGenerator (line 76) | @EnableMapRepositories(basePackageClasses = PersonRepository.class, na...
    class MyBeanNameGenerator (line 82) | static class MyBeanNameGenerator extends AnnotationBeanNameGenerator {
      method generateBeanName (line 84) | @Override
    type PersonRepository (line 90) | interface PersonRepository extends CrudRepository<Person, String> {
    class Person (line 94) | static class Person {}

FILE: src/test/java/org/springframework/data/keyvalue/repository/SimpleKeyValueRepositoryUnitTests.java
  class SimpleKeyValueRepositoryUnitTests (line 48) | @ExtendWith(MockitoExtension.class)
    method setUp (line 55) | @BeforeEach
    method saveNewWithNumericId (line 64) | @Test // DATACMNS-525
    method testDoubleSave (line 76) | @Test // DATACMNS-525
    method multipleSave (line 89) | @Test // DATACMNS-525
    method deleteEntity (line 100) | @Test // DATACMNS-525
    method deleteById (line 111) | @Test // DATACMNS-525
    method deleteAllById (line 119) | @Test // DATAKV-330
    method deleteAll (line 128) | @Test // DATACMNS-525
    method findAllIds (line 136) | @Test // DATACMNS-525
    method existsByIdReturnsFalseForEmptyOptional (line 146) | @Test // DATAKV-186
    method existsByIdReturnsTrueWhenOptionalValuePresent (line 154) | @Test // DATAKV-186
    method findAllWithPageableShouldDelegateToOperationsCorrectlyWhenPageableDoesNotContainSort (line 162) | @Test // DATACMNS-525
    method findAllWithPageableShouldDelegateToOperationsCorrectlyWhenPageableContainsSort (line 170) | @Test // DATACMNS-525
    method findAllShouldFallbackToFindAllOfWhenGivenNullPageable (line 179) | @Test // DATACMNS-525
    method getEntityInformationFor (line 187) | @SuppressWarnings("unchecked")
    class Foo (line 196) | static class Foo {
      method Foo (line 203) | Foo(String name) {
      method Foo (line 207) | public Foo() {}
      method getId (line 209) | public String getId() {
      method getLongValue (line 213) | public Long getLongValue() {
      method getName (line 217) | public String getName() {
      method getBar (line 221) | public Bar getBar() {
      method setId (line 225) | public void setId(String id) {
      method setLongValue (line 229) | public void setLongValue(Long longValue) {
      method setName (line 233) | public void setName(String name) {
      method setBar (line 237) | public void setBar(Bar bar) {
    class Bar (line 242) | private static class Bar {
      method getBar (line 246) | public String getBar() {
      method setBar (line 250) | public void setBar(String bar) {
    class WithNumericId (line 255) | @Persistent

FILE: src/test/java/org/springframework/data/keyvalue/repository/query/AbstractQueryCreatorTestBase.java
  class AbstractQueryCreatorTestBase (line 52) | @ExtendWith(MockitoExtension.class)
    method equalsReturnsTrueWhenMatching (line 68) | @Test // DATACMNS-525
    method equalsReturnsFalseWhenNotMatching (line 73) | @Test // DATACMNS-525
    method notEqualsReturnsTrueWhenMatching (line 78) | @Test // GH-603
    method notEqualsReturnsFalseWhenNotMatching (line 83) | @Test // GH-603
    method isTrueAssertedProperlyWhenTrue (line 88) | @Test // DATACMNS-525
    method isTrueAssertedProperlyWhenFalse (line 93) | @Test // DATACMNS-525
    method isFalseAssertedProperlyWhenTrue (line 98) | @Test // DATACMNS-525
    method isFalseAssertedProperlyWhenFalse (line 103) | @Test // DATACMNS-525
    method isNullAssertedProperlyWhenAttributeIsNull (line 108) | @Test // DATACMNS-525
    method isNullAssertedProperlyWhenAttributeIsNotNull (line 113) | @Test // DATACMNS-525
    method isNotNullFalseTrueWhenAttributeIsNull (line 118) | @Test // DATACMNS-525
    method isNotNullReturnsTrueAttributeIsNotNull (line 123) | @Test // DATACMNS-525
    method startsWithReturnsTrueWhenMatching (line 128) | @Test // DATACMNS-525
    method startsWithReturnsFalseWhenNotMatching (line 133) | @Test // DATACMNS-525
    method likeReturnsTrueWhenMatching (line 138) | @Test // DATACMNS-525
    method likeReturnsFalseWhenNotMatching (line 143) | @Test // DATACMNS-525
    method notLikeReturnsTrueWhenMatching (line 148) | @Test // GH-603
    method notLikeReturnsFalseWhenNotMatching (line 153) | @Test // GH-603
    method endsWithReturnsTrueWhenMatching (line 158) | @Test // DATACMNS-525
    method endsWithReturnsFalseWhenNotMatching (line 163) | @Test // DATACMNS-525
    method startsWithIgnoreCaseReturnsTrueWhenMatching (line 168) | @Test // DATACMNS-525
    method greaterThanReturnsTrueForHigherValues (line 174) | @Test // DATACMNS-525
    method greaterThanReturnsFalseForLowerValues (line 179) | @Test // DATACMNS-525
    method afterReturnsTrueForHigherValues (line 184) | @Test // DATACMNS-525
    method afterReturnsFalseForLowerValues (line 189) | @Test // DATACMNS-525
    method greaterThanEaualsReturnsTrueForHigherValues (line 194) | @Test // DATACMNS-525
    method greaterThanEqualsReturnsTrueForEqualValues (line 199) | @Test // DATACMNS-525
    method greaterThanEqualsReturnsFalseForLowerValues (line 204) | @Test // DATACMNS-525
    method lessThanReturnsTrueForHigherValues (line 209) | @Test // DATACMNS-525
    method lessThanReturnsFalseForLowerValues (line 214) | @Test // DATACMNS-525
    method beforeReturnsTrueForLowerValues (line 219) | @Test // DATACMNS-525
    method beforeReturnsFalseForHigherValues (line 224) | @Test // DATACMNS-525
    method lessThanEaualsReturnsTrueForHigherValues (line 229) | @Test // DATACMNS-525
    method lessThanEaualsReturnsTrueForEqualValues (line 234) | @Test // DATACMNS-525
    method lessThanEqualsReturnsFalseForLowerValues (line 239) | @Test // DATACMNS-525
    method betweenEqualsReturnsTrueForValuesInBetween (line 244) | @Test // DATACMNS-525
    method betweenEqualsReturnsFalseForHigherValues (line 249) | @Test // DATACMNS-525
    method betweenEqualsReturnsFalseForLowerValues (line 254) | @Test // DATACMNS-525
    method connectByAndReturnsTrueWhenAllPropertiesMatching (line 259) | @Test // DATACMNS-525
    method connectByAndReturnsFalseWhenOnlyFewPropertiesMatch (line 264) | @Test // DATACMNS-525
    method connectByOrReturnsTrueWhenOnlyFewPropertiesMatch (line 269) | @Test // DATACMNS-525
    method connectByOrReturnsTrueWhenAllPropertiesMatch (line 274) | @Test // DATACMNS-525
    method regexReturnsTrueWhenMatching (line 279) | @Test // DATACMNS-525
    method regexReturnsFalseWhenNotMatching (line 284) | @Test // DATACMNS-525
    method inReturnsMatchCorrectly (line 289) | @Test // DATAKV-169
    method inNotMatchingReturnsCorrectly (line 298) | @Test // DATAKV-169
    method inWithNullCompareValuesCorrectly (line 307) | @Test // DATAKV-169
    method inWithNullSourceValuesMatchesCorrectly (line 316) | @Test // DATAKV-169
    method inMatchesNullValuesCorrectly (line 326) | @Test // DATAKV-169
    method notInReturnsMatchCorrectly (line 338) | @Test // GH-603
    method notInNotMatchingReturnsCorrectly (line 347) | @Test // GH-603
    method notInWithNullCompareValuesCorrectly (line 356) | @Test // GH-603
    method notInWithNullSourceValuesMatchesCorrectly (line 365) | @Test // GH-603
    method notInMatchesNullValuesCorrectly (line 375) | @Test // GH-603
    method noDerivedQueryArgumentsMatchesAlways (line 385) | @Test // DATAKV-185
    method evaluate (line 392) | protected Evaluation evaluate(String methodName, Object... args) {
    method createEvaluation (line 400) | protected abstract Evaluation createEvaluation(CRITERIA criteria);
    method createQueryForMethodWithArgs (line 402) | protected KeyValueQuery<CRITERIA> createQueryForMethodWithArgs(String ...
    method getMethod (line 426) | private Method getMethod(Class<?> type, String methodName, Class<?>[] ...
    method queryCreator (line 457) | protected abstract QUERY_CREATOR queryCreator(PartTree partTree, Param...
    method finalizeQuery (line 459) | protected abstract KeyValueQuery<CRITERIA> finalizeQuery(KeyValueQuery...
    type PersonRepository (line 461) | interface PersonRepository extends CrudRepository<Person, String> {
      method findBy (line 464) | Person findBy();
      method findByFirstname (line 467) | Person findByFirstname(String firstname);
      method findByFirstnameNot (line 470) | Person findByFirstnameNot(String firstname);
      method findBySkinChangerIsTrue (line 473) | Person findBySkinChangerIsTrue();
      method findBySkinChangerIsFalse (line 476) | Person findBySkinChangerIsFalse();
      method findByLastnameIsNull (line 479) | Person findByLastnameIsNull();
      method findByLastnameIsNotNull (line 482) | Person findByLastnameIsNotNull();
      method findByFirstnameStartingWith (line 485) | Person findByFirstnameStartingWith(String firstanme);
      method findByFirstnameIgnoreCase (line 487) | Person findByFirstnameIgnoreCase(String firstanme);
      method findByBirthdayAfter (line 490) | Person findByBirthdayAfter(Date date);
      method findByAgeGreaterThan (line 493) | Person findByAgeGreaterThan(Integer age);
      method findByAgeGreaterThanEqual (line 496) | Person findByAgeGreaterThanEqual(Integer age);
      method findByBirthdayBefore (line 499) | Person findByBirthdayBefore(Date date);
      method findByAgeLessThan (line 502) | Person findByAgeLessThan(Integer age);
      method findByAgeLessThanEqual (line 505) | Person findByAgeLessThanEqual(Integer age);
      method findByAgeBetween (line 508) | Person findByAgeBetween(Integer low, Integer high);
      method findByFirstnameLike (line 511) | Person findByFirstnameLike(String firstname);
      method findByFirstnameNotLike (line 514) | Person findByFirstnameNotLike(String firstname);
      method findByFirstnameEndingWith (line 517) | Person findByFirstnameEndingWith(String firstname);
      method findByAgeGreaterThanAndLastname (line 519) | Person findByAgeGreaterThanAndLastname(Integer age, String lastname);
      method findByAgeGreaterThanOrLastname (line 521) | Person findByAgeGreaterThanOrLastname(Integer age, String lastname);
      method findByLastnameMatches (line 524) | Person findByLastnameMatches(String lastname);
      method findByFirstnameIn (line 527) | Person findByFirstnameIn(List<String> in);
      method findByFirstnameNotIn (line 530) | Person findByFirstnameNotIn(List<String> in);
    type Evaluation (line 534) | public interface Evaluation {
      method against (line 535) | Boolean against(Object candidate);
      method evaluate (line 537) | boolean evaluate();
    class Person (line 540) | public static class Person {
      method Person (line 548) | public Person() {}
      method Person (line 550) | Person(String firstname, int age) {
      method skinChanger (line 556) | Person skinChanger(boolean isSkinChanger) {
      method named (line 561) | Person named(String lastname) {
      method bornAt (line 566) | Person bornAt(Date date) {
      method getId (line 571) | public String getId() {
      method getFirstname (line 575) | public String getFirstname() {
      method getLastname (line 579) | public String getLastname() {
      method getAge (line 583) | public int getAge() {
      method isSkinChanger (line 587) | public boolean isSkinChanger() {
      method getBirthday (line 591) | public Date getBirthday() {
      method setId (line 595) | public void setId(String id) {
      method setFirstname (line 599) | public void setFirstname(String firstname) {
      method setLastname (line 603) | public void setLastname(String lastname) {
      method setAge (line 607) | public void setAge(int age) {
      method setSkinChanger (line 611) | public void setSkinChanger(boolean isSkinChanger) {
      method setBirthday (line 615) | public void setBirthday(Date birthday) {

FILE: src/test/java/org/springframework/data/keyvalue/repository/query/CachingKeyValuePartTreeQueryUnitTests.java
  class CachingKeyValuePartTreeQueryUnitTests (line 45) | @ExtendWith(MockitoExtension.class)
    method setUp (line 52) | @BeforeEach
    method cachedSpelExpressionShouldBeReusedWithNewContext (line 62) | @Test // DATAKV-137
    type Repo (line 80) | static interface Repo {
      method findByFirstname (line 82) | List<Person> findByFirstname(String firstname);

FILE: src/test/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQueryUnitTests.java
  class KeyValuePartTreeQueryUnitTests (line 48) | @ExtendWith(MockitoExtension.class)
    method spelExpressionAndContextShouldNotBeReused (line 55) | @Test // DATAKV-115
    method shouldApplyPageableParameterToCollectionQuery (line 78) | @Test // DATAKV-142
    method shouldAllowProjectionQueries (line 99) | @Test // GH-563
    method shouldApplyDerivedMaxResultsToQuery (line 120) | @Test // DATAKV-142
    method shouldApplyDerivedMaxResultsToQueryWithParameters (line 138) | @Test // DATAKV-142
    method shouldUseCountForExists (line 161) | @Test // GH-385
    method shouldUseCountForCount (line 181) | @Test // GH-71
    type Repo (line 201) | interface Repo {
      method findByFirstname (line 203) | List<Person> findByFirstname(String firstname);
      method existsByFirstname (line 205) | boolean existsByFirstname(String firstname);
      method countByFirstname (line 207) | int countByFirstname(String firstname);
      method findBy (line 209) | List<Person> findBy(Pageable page);
      method findTop3By (line 211) | List<Person> findTop3By();
      method findTop3ByFirstname (line 213) | List<Person> findTop3ByFirstname(String firstname);
      method findProjectionByFirstname (line 215) | PersonProjection findProjectionByFirstname(String firstname);
    type PersonProjection (line 218) | interface PersonProjection {
      method getFirstname (line 219) | String getFirstname();

FILE: src/test/java/org/springframework/data/keyvalue/repository/query/PredicateQueryCreatorUnitTests.java
  class PredicateQueryCreatorUnitTests (line 31) | class PredicateQueryCreatorUnitTests extends AbstractQueryCreatorTestBas...
    method startsWithIgnoreCaseReturnsTrueWhenMatching (line 33) | @Override
    method queryCreator (line 39) | @Override
    method finalizeQuery (line 44) | @Override
    method createEvaluation (line 49) | @Override
    class PredicateEvaluation (line 54) | static class PredicateEvaluation implements Evaluation {
      method PredicateEvaluation (line 59) | PredicateEvaluation(Predicate<?> expression) {
      method against (line 63) | public Boolean against(Object candidate) {
      method evaluate (line 68) | public boolean evaluate() {

FILE: src/test/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreatorUnitTests.java
  class SpelQueryCreatorUnitTests (line 28) | public class SpelQueryCreatorUnitTests extends AbstractQueryCreatorTestB...
    method queryCreator (line 30) | @Override
    method finalizeQuery (line 35) | @Override
    method createEvaluation (line 43) | @Override
    class SpelEvaluation (line 48) | static class SpelEvaluation implements Evaluation {
      method SpelEvaluation (line 53) | SpelEvaluation(SpelExpression expression) {
      method against (line 57) | public Boolean against(Object candidate) {
      method evaluate (line 62) | public boolean evaluate() {

FILE: src/test/java/org/springframework/data/keyvalue/repository/support/KeyValueQuerydslUtilsUnitTests.java
  class KeyValueQuerydslUtilsUnitTests (line 42) | class KeyValueQuerydslUtilsUnitTests {
    method setUp (line 47) | @BeforeEach
    method toOrderSpecifierThrowsExceptioOnNullPathBuilder (line 54) | @Test // DATACMNS-525
    method toOrderSpecifierReturnsEmptyArrayWhenSortIsUnsorted (line 59) | @Test // DATACMNS-525, DATAKV-197
    method toOrderSpecifierConvertsSimpleAscSortCorrectly (line 64) | @Test // DATACMNS-525
    method toOrderSpecifierConvertsSimpleDescSortCorrectly (line 74) | @Test // DATACMNS-525
    method toOrderSpecifierConvertsSortCorrectlyAndRetainsArgumentOrder (line 84) | @Test // DATACMNS-525
    method toOrderSpecifierConvertsSortWithNullHandlingCorrectly (line 94) | @Test // DATACMNS-525

FILE: src/test/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactoryBeanUnitTests.java
  class KeyValueRepositoryFactoryBeanUnitTests (line 36) | class KeyValueRepositoryFactoryBeanUnitTests {
    method setUp (line 40) | @BeforeEach
    method rejectsNullKeyValueOperations (line 46) | @Test // DATAKV-123
    method rejectsNullQueryCreator (line 51) | @Test // DATAKV-123
    method rejectsUninitializedInstance (line 56) | @Test // DATAKV-123
    method rejectsInstanceWithoutKeyValueOperations (line 61) | @SuppressWarnings("unchecked")
    method rejectsInstanceWithoutQueryCreator (line 73) | @Test // DATAKV-123
    method createsRepositoryFactory (line 80) | @Test // DATAKV-123
    method rejectsNullQueryType (line 95) | @Test // DATAKV-112
    type SampleRepository (line 100) | interface SampleRepository extends Repository<Object, Object> {}

FILE: src/test/java/org/springframework/data/map/AbstractRepositoryUnitTests.java
  class AbstractRepositoryUnitTests (line 48) | public abstract class AbstractRepositoryUnitTests<T extends AbstractRepo...
    method setup (line 60) | @BeforeEach
    method findBy (line 69) | @Test // DATACMNS-525
    method findByFirstname (line 77) | @Test // DATAKV-137
    method combindedFindUsingAnd (line 86) | @Test // DATACMNS-525, DATAKV-137
    method findPage (line 95) | @Test // DATACMNS-525
    method findByConnectingOr (line 111) | @Test // DATACMNS-525
    method singleEntityExecution (line 119) | @Test // DATACMNS-525, DATAKV-137
    method findAllShouldRespectSort (line 128) | @Test // DATACMNS-525
    method derivedFinderShouldRespectSort (line 138) | @Test // DATACMNS-525
    method projectsResultToInterface (line 148) | @Test // DATAKV-121
    method projectsResultToDynamicInterface (line 159) | @Test // DATAKV-121
    method findsByValueInCollectionCorrectly (line 170) | @Test // DATAKV-169
    method findsByValueInCollectionCorrectlyWhenTargetPathContainsNullValue (line 181) | @Test // DATAKV-169
    method findsByValueInCollectionCorrectlyWhenTargetPathAndCollectionContainNullValue (line 193) | @Test // DATAKV-169
    method createKeyValueRepositoryFactory (line 208) | protected KeyValueRepositoryFactory createKeyValueRepositoryFactory(Ke...
    method getRepository (line 212) | protected abstract T getRepository(KeyValueRepositoryFactory factory);
    type PersonRepository (line 214) | public interface PersonRepository extends CrudRepository<Person, Strin...
      method findByAge (line 216) | List<Person> findByAge(int age);
      method findByFirstname (line 218) | List<Person> findByFirstname(String firstname);
      method findByFirstnameAndAge (line 220) | List<Person> findByFirstnameAndAge(String firstname, int age);
      method findByAge (line 222) | Page<Person> findByAge(int age, Pageable page);
      method findByAgeOrFirstname (line 224) | List<Person> findByAgeOrFirstname(int age, String firstname);
      method findByAgeAndFirstname (line 226) | Person findByAgeAndFirstname(int age, String firstname);
      method findByAgeGreaterThanOrderByAgeAscFirstnameDesc (line 228) | List<Person> findByAgeGreaterThanOrderByAgeAscFirstnameDesc(int age);
      method findByAgeGreaterThan (line 230) | List<PersonSummary> findByAgeGreaterThan(int age, Sort sort);
      method findByAgeGreaterThan (line 232) | <T> List<T> findByAgeGreaterThan(int age, Sort sort, Class<T> projec...
      method findByFirstnameIn (line 234) | List<Person> findByFirstnameIn(List<String> firstname);
    type PersonSummary (line 237) | interface PersonSummary {
      method getFirstname (line 239) | String getFirstname();

FILE: src/test/java/org/springframework/data/map/CachingQuerySimpleKeyValueRepositoryUnitTests.java
  class CachingQuerySimpleKeyValueRepositoryUnitTests (line 33) | @Disabled
    method createKeyValueRepositoryFactory (line 36) | @Override

FILE: src/test/java/org/springframework/data/map/MapDbIntegrationTests.java
  class MapDbIntegrationTests (line 41) | @SpringJUnitConfig
    class TestConfiguration (line 44) | @Configuration
      method db (line 48) | @Bean
      method store (line 53) | @Bean
    method shouldStoreEntriesInMapDb (line 76) | @Test
    type PersonRepository (line 92) | interface PersonRepository extends KeyValueRepository<Person, String> {
      method countByLastname (line 94) | long countByLastname(String lastname);
    class Person (line 97) | static class Person {
      method Person (line 103) | Person(String firstname, String lastname) {

FILE: src/test/java/org/springframework/data/map/MapKeyValueAdapterUnitTests.java
  class MapKeyValueAdapterUnitTests (line 34) | class MapKeyValueAdapterUnitTests {
    method setUp (line 45) | @BeforeEach
    method putShouldThrowExceptionWhenAddingNullId (line 50) | @Test // DATACMNS-525
    method putShouldThrowExceptionWhenCollectionIsNullValue (line 55) | @Test // DATACMNS-525
    method putReturnsNullWhenNoObjectForIdPresent (line 60) | @Test // DATACMNS-525
    method putShouldReturnPreviousObjectForIdWhenAddingNewOneWithSameIdPresent (line 65) | @Test // DATACMNS-525
    method containsShouldThrowExceptionWhenIdIsNull (line 72) | @Test // DATACMNS-525
    method containsShouldThrowExceptionWhenTypeIsNull (line 77) | @Test // DATACMNS-525
    method containsShouldReturnFalseWhenNoElementsPresent (line 82) | @Test // DATACMNS-525
    method containShouldReturnTrueWhenElementWithIdPresent (line 87) | @Test // DATACMNS-525
    method getShouldReturnNullWhenNoElementWithIdPresent (line 94) | @Test // DATACMNS-525
    method getShouldReturnElementWhenMatchingIdPresent (line 99) | @Test // DATACMNS-525
    method getShouldThrowExceptionWhenIdIsNull (line 106) | @Test // DATACMNS-525
    method getShouldThrowExceptionWhenTypeIsNull (line 111) | @Test // DATACMNS-525
    method getAllOfShouldReturnAllValuesOfGivenCollection (line 116) | @Test // DATACMNS-525
    method getAllOfShouldThrowExceptionWhenTypeIsNull (line 126) | @Test // DATACMNS-525
    method deleteShouldReturnNullWhenGivenIdThatDoesNotExist (line 131) | @Test // DATACMNS-525
    method deleteShouldReturnDeletedObject (line 136) | @Test // DATACMNS-525
    method scanShouldIterateOverAvailableEntries (line 143) | @Test // DATAKV-99
    method scanShouldReturnEmptyIteratorWhenNoElementsAvailable (line 156) | @Test // DATAKV-99
    method scanDoesNotMixResultsFromMultipleKeyspaces (line 161) | @Test // DATAKV-99
    class SimpleObject (line 173) | static class SimpleObject {
      method SimpleObject (line 177) | public SimpleObject() {}
      method SimpleObject (line 179) | SimpleObject(String value) {
      method getStringValue (line 183) | public String getStringValue() {
      method setStringValue (line 187) | public void setStringValue(String stringValue) {

FILE: src/test/java/org/springframework/data/map/QuerydslKeyValuePredicateExecutorUnitTests.java
  class QuerydslKeyValuePredicateExecutorUnitTests (line 49) | class QuerydslKeyValuePredicateExecutorUnitTests extends AbstractReposit...
    method setUp (line 51) | @BeforeEach
    method findOneIsExecutedCorrectly (line 56) | @Test // DATACMNS-525
    method findAllIsExecutedCorrectly (line 63) | @Test // DATACMNS-525
    method findWithPaginationWorksCorrectly (line 70) | @Test // DATACMNS-525
    method findAllUsingOrderSpecifierWorksCorrectly (line 86) | @Test // DATACMNS-525
    method findAllUsingPageableWithSortWorksCorrectly (line 95) | @Test // DATACMNS-525
    method findAllUsingPagableWithQSortWorksCorrectly (line 104) | @Test // DATACMNS-525
    method findAllWithOrderSpecifierWorksCorrectly (line 113) | @Test // DATAKV-90
    method findAllShouldRequireSort (line 121) | @Test // DATAKV-90, DATAKV-197
    method findAllShouldAllowUnsortedFindAll (line 126) | @Test // DATAKV-90, DATAKV-197
    method executesExistsCorrectly (line 134) | @Test // DATAKV-95
    method shouldSupportFindAllWithPredicateAndSort (line 139) | @Test // DATAKV-96
    method throwsExceptionIfMoreThanOneResultIsFound (line 151) | @Test // DATAKV-179
    method findByShouldReturnFirst (line 158) | @Test // GH-397
    method findByShouldReturnOne (line 171) | @Test // GH-397
    method findByShouldReturnFirstWithProjection (line 182) | @Test // GH-397
    method findByShouldReturnOneWithProjection (line 193) | @Test // GH-397
    method findByShouldReturnAll (line 204) | @Test // GH-397
    method findByShouldReturnAllSorted (line 212) | @Test // GH-397
    method findByShouldReturnAllWithProjection (line 226) | @Test // GH-397
    method findByShouldReturnPage (line 235) | @Test // GH-397
    method findByShouldReturnStream (line 251) | @Test // GH-397
    method findByShouldReturnStreamWithProjection (line 259) | @Test // GH-397
    method findByShouldReturnCount (line 268) | @Test // GH-397
    method findByShouldReturnExists (line 276) | @Test // GH-397
    type PersonProjection (line 286) | interface PersonProjection {
      method getFirstname (line 287) | String getFirstname();
    class PersonDto (line 290) | static class PersonDto {
      method getFirstname (line 294) | public String getFirstname() {
      method setFirstname (line 298) | public void setFirstname(String firstname) {
    method getRepository (line 303) | @Override
    type QPersonRepository (line 308) | interface QPersonRepository extends org.springframework.data.map.Abstr...

FILE: src/test/java/org/springframework/data/map/SimpleKeyValueRepositoryUnitTests.java
  class SimpleKeyValueRepositoryUnitTests (line 28) | public class SimpleKeyValueRepositoryUnitTests extends AbstractRepositor...
    method getRepository (line 30) | protected PersonRepository getRepository(KeyValueRepositoryFactory fac...

FILE: src/test/java/org/springframework/data/map/repository/config/MapRepositoriesConfigurationExtensionIntegrationTests.java
  class MapRepositoriesConfigurationExtensionIntegrationTests (line 66) | class MapRepositoriesConfigurationExtensionIntegrationTests {
    method registersDefaultTemplateIfReferenceNotCustomized (line 68) | @Test // DATAKV-86
    method doesNotRegisterDefaultTemplateIfReferenceIsCustomized (line 78) | @Test // DATAKV-86
    method shouldUseCustomAdapter (line 89) | @Test // GH-358
    method considersMapTypeConfiguredOnAnnotation (line 103) | @Test // DATAKV-87
    method doesNotConsiderMapConfiguredIfTemplateIsPresent (line 109) | @Test // DATAKV-87
    method considersSortAccessorConfiguredOnAnnotation (line 115) | @Test // GH-565
    method considersQueryEngineConfiguration (line 121) | @Test // GH-576
    method considersQueryEngineAndSortAccessorConfiguration (line 136) | @Test // GH-576
    method assertKeyValueTemplateWithAdapterFor (line 156) | private static void assertKeyValueTemplateWithAdapterFor(Class<?> mapT...
    method assertKeyValueTemplateWithSortAccessorFor (line 167) | private static void assertKeyValueTemplateWithSortAccessorFor(Class<?>...
    method considersDefaultQueryCreator (line 180) | @Test // GH-576
    method considersCustomQueryCreator (line 191) | @Test // GH-576
    class Config (line 203) | @Configuration
    class ConfigWithCustomTemplateReference (line 208) | @Configuration
    class ConfigWithOverriddenTemplateReference (line 212) | @Configuration
      method mapKeyValueTemplate (line 217) | @Bean
      method keyValueAdapter (line 222) | @Bean
    class ConfigWithCustomizedMapType (line 234) | @Configuration
    class ConfigWithCustomizedMapTypeAndExplicitDefinitionOfKeyValueTemplate (line 238) | @Configuration
      method mapKeyValueTemplate (line 242) | @Bean
    class ConfigWithQueryEngine (line 248) | @EnableMapRepositories(queryEngineFactory = JustSpelQueryEngineFactory...
    class JustSpelQueryEngineFactory (line 251) | static class JustSpelQueryEngineFactory implements QueryEngineFactory {
      method create (line 253) | @Override
    class ConfigWithCustomizedSortAccessor (line 260) | @EnableMapRepositories(sortAccessor = PathSortAccessor.class)
    class ConfigWithQueryEngineAndCustomizedSortAccessor (line 263) | @EnableMapRepositories(sortAccessor = PathSortAccessor.class, queryEng...
    class ConfigWithCustomQueryCreator (line 266) | @EnableMapRepositories(queryCreator = MyQueryCreator.class, considerNe...
    class SpelQueryEngineFactory (line 270) | static class SpelQueryEngineFactory implements QueryEngineFactory {
      method SpelQueryEngineFactory (line 274) | public SpelQueryEngineFactory(SortAccessor<Comparator<?>> sortAccess...
      method create (line 278) | @Override
    class MyQueryCreator (line 285) | static class MyQueryCreator extends AbstractQueryCreator<KeyValueQuery...
      method MyQueryCreator (line 287) | public MyQueryCreator(PartTree tree) {
      method MyQueryCreator (line 291) | public MyQueryCreator(PartTree tree, ParameterAccessor parameters) {
      method create (line 295) | @Override
      method and (line 300) | @Override
      method or (line 305) | @Override
      method complete (line 310) | @Override
    type PersonRepository (line 316) | interface PersonRepository extends KeyValueRepository<Person, String> {
    class Person (line 320) | static class Person {
      method getId (line 324) | public String getId() {
      method getName (line 328) | public String getName() {
      method setId (line 332) | public void setId(String id) {
      method setName (line 336) | public void setName(String name) {

FILE: src/test/java/org/springframework/data/map/repository/config/MapRepositoryRegistrarWithFullDefaultingIntegrationTests.java
  class MapRepositoryRegistrarWithFullDefaultingIntegrationTests (line 37) | @ExtendWith(SpringExtension.class)
    class Config (line 41) | @Configuration
    method shouldEnableMapRepositoryCorrectly (line 49) | @Test // DATAKV-86
    class Person (line 54) | static class Person {
      method getId (line 59) | public String getId() {
      method getFirstname (line 63) | public String getFirstname() {
      method setId (line 67) | public void setId(String id) {
      method setFirstname (line 71) | public void setFirstname(String firstname) {
    type PersonRepository (line 76) | interface PersonRepository extends CrudRepository<Person, String> {
      method findByFirstname (line 78) | List<Person> findByFirstname(String firstname);

FILE: src/test/java/org/springframework/data/map/repository/config/MapRepositoryRegistrarWithTemplateDefinitionIntegrationTests.java
  class MapRepositoryRegistrarWithTemplateDefinitionIntegrationTests (line 41) | @ExtendWith(SpringExtension.class)
    class Config (line 45) | @Configuration
      method keyValueTemplate (line 49) | @Bean
    method shouldEnableMapRepositoryCorrectly (line 57) | @Test // DATACMNS-525
    class Person (line 62) | static class Person {
      method getId (line 67) | public String getId() {
      method getFirstname (line 71) | public String getFirstname() {
      method setId (line 75) | public void setId(String id) {
      method setFirstname (line 79) | public void setFirstname(String firstname) {
    type PersonRepository (line 84) | interface PersonRepository extends CrudRepository<Person, String> {
      method findByFirstname (line 86) | List<Person> findByFirstname(String firstname);
Condensed preview — 158 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (519K chars).
[
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 823,
    "preview": "<!--\n\nThank you for proposing a pull request. This template will guide you through the essential steps necessary for a p"
  },
  {
    "path": ".github/README.template.adoc",
    "chars": 6180,
    "preview": "= Spring Data KeyValue image:https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=0230"
  },
  {
    "path": ".github/dco.yml",
    "chars": 26,
    "preview": "require:\n  members: false\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 627,
    "preview": "name: CI Build\n\non:\n  workflow_dispatch:\n  push:\n    branches: [ main, 'issue/**' ]\n\npermissions: read-all\n\njobs:\n  buil"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "chars": 495,
    "preview": "# GitHub Actions for CodeQL Scanning\n\nname: \"CodeQL Advanced\"\n\non:\n  push:\n  pull_request:\n  workflow_dispatch:\n  schedu"
  },
  {
    "path": ".github/workflows/project.yml",
    "chars": 2004,
    "preview": "# GitHub Actions to automate GitHub issues for Spring Data Project Management\n\nname: Spring Data GitHub Issues\n\non:\n  is"
  },
  {
    "path": ".github/workflows/snapshots.yml",
    "chars": 794,
    "preview": "name: Snapshots\n\non:\n  workflow_dispatch:\n  push:\n    branches: [ main, 'issue/**' ]\n\npermissions: read-all\n\njobs:\n  bui"
  },
  {
    "path": ".gitignore",
    "chars": 148,
    "preview": "target/\n.settings/\n.project\n.classpath\n.springBeans\n.DS_Store\n*.iml\n*.ipr\n*.iws\n/.idea/\nnode_modules\nnode\npackage-lock.j"
  },
  {
    "path": ".mvn/extensions.xml",
    "chars": 241,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<extensions>\n\t<extension>\n\t\t<groupId>io.spring.develocity.conventions</groupId>\n\t"
  },
  {
    "path": ".mvn/jvm.config",
    "chars": 835,
    "preview": "--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED\n--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-U"
  },
  {
    "path": ".mvn/wrapper/maven-wrapper.properties",
    "chars": 150,
    "preview": "#Thu Jul 17 13:59:50 CEST 2025\ndistributionUrl=https\\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.1"
  },
  {
    "path": "CI.adoc",
    "chars": 129,
    "preview": "= Continuous Integration\n\n== Running CI tasks locally\n\nYou can run CI jobs locally using Docker and act[https://nektosac"
  },
  {
    "path": "CONTRIBUTING.adoc",
    "chars": 189,
    "preview": "= Spring Data contribution guidelines\n\nYou find the contribution guidelines for Spring Data projects https://github.com/"
  },
  {
    "path": "LICENSE.txt",
    "chars": 11360,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.adoc",
    "chars": 2485,
    "preview": "= Spring Data KeyValue image:https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=0230"
  },
  {
    "path": "SECURITY.adoc",
    "chars": 680,
    "preview": "= Security Policy\n\n== Reporting a Vulnerability\n\nPlease, https://github.com/spring-projects/security-advisories/security"
  },
  {
    "path": "mvnw",
    "chars": 9114,
    "preview": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Softwa"
  },
  {
    "path": "mvnw.cmd",
    "chars": 5811,
    "preview": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software F"
  },
  {
    "path": "package.json",
    "chars": 302,
    "preview": "{\n  \"dependencies\": {\n    \"antora\": \"3.2.0-alpha.6\",\n    \"@antora/atlas-extension\": \"1.0.0-alpha.2\",\n    \"@antora/collec"
  },
  {
    "path": "pom.xml",
    "chars": 3196,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2"
  },
  {
    "path": "settings.xml",
    "chars": 900,
    "preview": "<settings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"\n          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
  },
  {
    "path": "src/main/antora/antora-playbook.yml",
    "chars": 1341,
    "preview": "# PACKAGES antora@3.2.0-alpha.2 @antora/atlas-extension:1.0.0-alpha.1 @antora/collector-extension@1.0.0-alpha.3 @springi"
  },
  {
    "path": "src/main/antora/antora.yml",
    "chars": 315,
    "preview": "name: data-keyvalue\nversion: true\ntitle: Spring Data KeyValue\nnav:\n  - modules/ROOT/nav.adoc\next:\n  collector:\n    - run"
  },
  {
    "path": "src/main/antora/modules/ROOT/nav.adoc",
    "chars": 624,
    "preview": "* xref:index.adoc[Overview]\n* xref:keyvalue.adoc[]\n* xref:keyvalue/template.adoc[]\n\n* xref:repositories.adoc[]\n** xref:r"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/commons/upgrade.adoc",
    "chars": 360,
    "preview": "include::{commons}@data-commons::page$upgrade.adoc[]\n\nOnce you’ve decided to upgrade your application, you can find deta"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/index.adoc",
    "chars": 1078,
    "preview": "[[spring-data-key-value-reference-guide]]\n= Spring Data Key-Value\n:revnumber: {version}\n:revdate: {localdate}\n:feature-s"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/keyvalue/repository/map-repositories.adoc",
    "chars": 1549,
    "preview": "[[key-value.repositories.map]]\n= Map Repositories\n\nMap repositories reside on top of the `KeyValueTemplate`.\nUsing the d"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/keyvalue/template.adoc",
    "chars": 4292,
    "preview": "[[key-value.template]]\n= Template API\n\nIn its very basic shape, the `KeyValueTemplate` uses a `MapAdapter` that wraps a "
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/keyvalue/value-expressions.adoc",
    "chars": 63,
    "preview": "include::{commons}@data-commons::page$value-expressions.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/keyvalue.adoc",
    "chars": 2027,
    "preview": "[[key-value]]\n= KeyValue\n\nSpring Data KeyValue provides easy configuration and access to `Map` like structures that asso"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/core-concepts.adoc",
    "chars": 211,
    "preview": "include::{commons}@data-commons::page$repositories/core-concepts.adoc[]\n\n[[redis.entity-persistence.state-detection-stra"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/core-domain-events.adoc",
    "chars": 77,
    "preview": "include::{commons}@data-commons::page$repositories/core-domain-events.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc",
    "chars": 86,
    "preview": "[[core.extensions.querydsl]]\n= Querydsl\n\nSpring Data Redis does not support Querydsl.\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/create-instances.adoc",
    "chars": 75,
    "preview": "include::{commons}@data-commons::page$repositories/create-instances.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/custom-implementations.adoc",
    "chars": 81,
    "preview": "include::{commons}@data-commons::page$repositories/custom-implementations.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/definition.adoc",
    "chars": 69,
    "preview": "include::{commons}@data-commons::page$repositories/definition.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/null-handling.adoc",
    "chars": 72,
    "preview": "include::{commons}@data-commons::page$repositories/null-handling.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/object-mapping.adoc",
    "chars": 60,
    "preview": "include::{commons}@data-commons::page$object-mapping.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/projections.adoc",
    "chars": 125,
    "preview": "[[cassandra.projections]]\n= Projections\n\ninclude::{commons}@data-commons::page$repositories/projections.adoc[leveloffset"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/query-keywords-reference.adoc",
    "chars": 83,
    "preview": "include::{commons}@data-commons::page$repositories/query-keywords-reference.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/query-methods-details.adoc",
    "chars": 80,
    "preview": "include::{commons}@data-commons::page$repositories/query-methods-details.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories/query-return-types-reference.adoc",
    "chars": 87,
    "preview": "include::{commons}@data-commons::page$repositories/query-return-types-reference.adoc[]\n"
  },
  {
    "path": "src/main/antora/modules/ROOT/pages/repositories.adoc",
    "chars": 431,
    "preview": "[[keyvalyue.repositories]]\n= KeyValue Repositories\n\nThis chapter explains the basic foundations of Spring Data repositor"
  },
  {
    "path": "src/main/antora/resources/antora-resources/antora.yml",
    "chars": 931,
    "preview": "version: ${antora-component.version}\nprerelease: ${antora-component.prerelease}\n\nasciidoc:\n  attributes:\n    attribute-m"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/annotation/KeySpace.java",
    "chars": 2116,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/annotation/package-info.java",
    "chars": 164,
    "preview": "/**\n * Key-Value annotations for declarative keyspace configuration.\n */\n@org.jspecify.annotations.NullMarked\npackage or"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/aot/KeyValueRuntimeHints.java",
    "chars": 2216,
    "preview": "/*\n * Copyright 2022-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/aot/package-info.java",
    "chars": 151,
    "preview": "/**\n * Support classes for key-value ahead of time computation\n */\n@org.jspecify.annotations.NullMarked\npackage org.spri"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/AbstractKeyValueAdapter.java",
    "chars": 2937,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/CriteriaAccessor.java",
    "chars": 1448,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/DefaultIdentifierGenerator.java",
    "chars": 3632,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/ForwardingCloseableIterator.java",
    "chars": 2147,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/GeneratingIdAccessor.java",
    "chars": 2850,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/IdentifierGenerator.java",
    "chars": 1088,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/IterableConverter.java",
    "chars": 1684,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java",
    "chars": 5731,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/KeyValueCallback.java",
    "chars": 1341,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java",
    "chars": 5828,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslator.java",
    "chars": 2054,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java",
    "chars": 13757,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/PathSortAccessor.java",
    "chars": 2127,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/PredicateQueryEngine.java",
    "chars": 3180,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/PropertyPathComparator.java",
    "chars": 3290,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/QueryEngine.java",
    "chars": 4481,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/QueryEngineFactory.java",
    "chars": 1323,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/SimplePropertyPathAccessor.java",
    "chars": 1463,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/SortAccessor.java",
    "chars": 1483,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/SpelCriteria.java",
    "chars": 2254,
    "preview": "/*\n * Copyright 2016-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/SpelCriteriaAccessor.java",
    "chars": 2129,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/SpelPropertyComparator.java",
    "chars": 3982,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java",
    "chars": 3684,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/SpelSortAccessor.java",
    "chars": 2710,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/UncategorizedKeyValueException.java",
    "chars": 1377,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/event/KeyValueEvent.java",
    "chars": 10355,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/event/package-info.java",
    "chars": 184,
    "preview": "/**\n * Support classes for key-value events, like standard persistence lifecycle events.\n */\n@org.jspecify.annotations.N"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/AnnotationBasedKeySpaceResolver.java",
    "chars": 2048,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/BasicKeyValuePersistentEntity.java",
    "chars": 3805,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/ClassNameKeySpaceResolver.java",
    "chars": 1174,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/KeySpaceResolver.java",
    "chars": 1213,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentEntity.java",
    "chars": 1851,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentProperty.java",
    "chars": 1622,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/PrefixKeyspaceResolver.java",
    "chars": 1445,
    "preview": "/*\n * Copyright 2022-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/context/KeyValueMappingContext.java",
    "chars": 3742,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/context/package-info.java",
    "chars": 162,
    "preview": "/**\n * Infrastructure for the Key-Value mapping context.\n */\n@org.jspecify.annotations.NullMarked\npackage org.springfram"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/mapping/package-info.java",
    "chars": 180,
    "preview": "/**\n * Infrastructure for the Key-Value mapping subsystem and keyspace resolution.\n */\n@org.jspecify.annotations.NullMar"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/package-info.java",
    "chars": 127,
    "preview": "/**\n * Core key/value implementation.\n */\n@org.jspecify.annotations.NullMarked\npackage org.springframework.data.keyvalue"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/query/KeyValueQuery.java",
    "chars": 3652,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/core/query/package-info.java",
    "chars": 145,
    "preview": "/**\n * Key/value specific query and abstractions.\n */\n@org.jspecify.annotations.NullMarked\npackage org.springframework.d"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/KeyValueRepository.java",
    "chars": 1005,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java",
    "chars": 7623,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/config/QueryCreatorType.java",
    "chars": 1668,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/config/package-info.java",
    "chars": 190,
    "preview": "/**\n * Support infrastructure for the configuration of key/value specific repositories.\n */\n@org.jspecify.annotations.Nu"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/package-info.java",
    "chars": 148,
    "preview": "/**\n * Key/value specific repository implementation.\n */\n@org.jspecify.annotations.NullMarked\npackage org.springframewor"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/query/CachingKeyValuePartTreeQuery.java",
    "chars": 2019,
    "preview": "/*\n * Copyright 2016-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java",
    "chars": 10687,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/query/PredicateQueryCreator.java",
    "chars": 9725,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreator.java",
    "chars": 7004,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/query/package-info.java",
    "chars": 218,
    "preview": "/**\n * Query derivation mechanism for key/value specific repositories providing a generic SpEL based implementation.\n */"
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueQuerydslUtils.java",
    "chars": 4369,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactory.java",
    "chars": 9869,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactoryBean.java",
    "chars": 4638,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/support/QuerydslKeyValuePredicateExecutor.java",
    "chars": 12680,
    "preview": "/*\n * Copyright 2021-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/support/QuerydslKeyValueRepository.java",
    "chars": 4474,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java",
    "chars": 5381,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/keyvalue/repository/support/package-info.java",
    "chars": 190,
    "preview": "/**\n * Support infrastructure for query derivation of key/value specific repositories.\n */\n@org.jspecify.annotations.Nul"
  },
  {
    "path": "src/main/java/org/springframework/data/map/KeySpaceStore.java",
    "chars": 3496,
    "preview": "/*\n * Copyright 2025-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/map/MapKeySpaceStore.java",
    "chars": 3079,
    "preview": "/*\n * Copyright 2025-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/map/MapKeyValueAdapter.java",
    "chars": 6189,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/map/package-info.java",
    "chars": 163,
    "preview": "/**\n * Repository implementation backed by generic {@link java.util.Map} instances.\n */\n@org.jspecify.annotations.NullMa"
  },
  {
    "path": "src/main/java/org/springframework/data/map/repository/config/EnableMapRepositories.java",
    "chars": 7670,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/map/repository/config/MapRepositoriesRegistrar.java",
    "chars": 1349,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/map/repository/config/MapRepositoryConfigurationExtension.java",
    "chars": 5036,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/main/java/org/springframework/data/map/repository/config/package-info.java",
    "chars": 188,
    "preview": "/**\n * Support infrastructure for the configuration of {@link java.util.Map} repositories.\n */\n@org.jspecify.annotations"
  },
  {
    "path": "src/main/resources/META-INF/spring/aot.factories",
    "chars": 113,
    "preview": "org.springframework.aot.hint.RuntimeHintsRegistrar=\\\n\torg.springframework.data.keyvalue.aot.KeyValueRuntimeHints\n"
  },
  {
    "path": "src/main/resources/META-INF/spring.factories",
    "chars": 153,
    "preview": "org.springframework.data.repository.core.support.RepositoryFactorySupport=org.springframework.data.keyvalue.repository.s"
  },
  {
    "path": "src/main/resources/license.txt",
    "chars": 14765,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "src/main/resources/notice.txt",
    "chars": 513,
    "preview": "Spring Data KeyValue 4.1 RC1 (2026.0.0)\nCopyright (c) 2015-2019 Pivotal Software, Inc.\n\nThis product is licensed to you "
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/CustomKeySpaceAnnotationWithAliasFor.java",
    "chars": 1368,
    "preview": "/*\n * Copyright 2016-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/Person.java",
    "chars": 1549,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/SubclassOfTypeWithCustomComposedKeySpaceAnnotation.java",
    "chars": 1132,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/TypeWithCustomComposedKeySpaceAnnotationUsingAliasFor.java",
    "chars": 1383,
    "preview": "/*\n * Copyright 2016-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/TypeWithDirectKeySpaceAnnotation.java",
    "chars": 958,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/TypeWithInhteritedPersistentAnnotationNotHavingKeySpace.java",
    "chars": 1074,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/TypeWithPersistentAnnotationNotHavingKeySpace.java",
    "chars": 968,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/DefaultIdentifierGeneratorUnitTests.java",
    "chars": 2180,
    "preview": "/*\n * Copyright 2016-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/ForwardingCloseableIteratorUnitTests.java",
    "chars": 2863,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/IterableConverterUnitTests.java",
    "chars": 1857,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslatorUnitTests.java",
    "chars": 2878,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateTests.java",
    "chars": 8074,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java",
    "chars": 19064,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/PredicateQueryEngineUnitTests.java",
    "chars": 4186,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/PropertyPathComparatorUnitTests.java",
    "chars": 5905,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/SpelPropertyComparatorUnitTests.java",
    "chars": 6199,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/SpelQueryEngineUnitTests.java",
    "chars": 4362,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/mapping/AnnotationBasedKeySpaceResolverUnitTests.java",
    "chars": 4026,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/mapping/BasicKeyValuePersistentEntityUnitTests.java",
    "chars": 3935,
    "preview": "/*\n * Copyright 2019-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/mapping/PrefixKeyspaceResolverUnitTests.java",
    "chars": 1096,
    "preview": "/*\n * Copyright 2022-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/core/mapping/context/KeyValueMappingContextUnitTests.java",
    "chars": 1588,
    "preview": "/*\n * Copyright 2021-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/MapRepositoriesRegistrarUnitTests.java",
    "chars": 3471,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/SimpleKeyValueRepositoryUnitTests.java",
    "chars": 6534,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/query/AbstractQueryCreatorTestBase.java",
    "chars": 17786,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/query/CachingKeyValuePartTreeQueryUnitTests.java",
    "chars": 3189,
    "preview": "/*\n * Copyright 2016-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQueryUnitTests.java",
    "chars": 9511,
    "preview": "/*\n * Copyright 2015-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/query/PredicateQueryCreatorUnitTests.java",
    "chars": 2245,
    "preview": "/*\n * Copyright 2024-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreatorUnitTests.java",
    "chars": 2247,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/support/KeyValueQuerydslUtilsUnitTests.java",
    "chars": 3447,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactoryBeanUnitTests.java",
    "chars": 3463,
    "preview": "/*\n * Copyright 2016-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/AbstractRepositoryUnitTests.java",
    "chars": 7452,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/CachingQuerySimpleKeyValueRepositoryUnitTests.java",
    "chars": 1731,
    "preview": "/*\n * Copyright 2016-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/MapDbIntegrationTests.java",
    "chars": 3024,
    "preview": "/*\n * Copyright 2025-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/MapKeyValueAdapterUnitTests.java",
    "chars": 5635,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/QuerydslKeyValuePredicateExecutorUnitTests.java",
    "chars": 10148,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/SimpleKeyValueRepositoryUnitTests.java",
    "chars": 1280,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/repository/config/MapRepositoriesConfigurationExtensionIntegrationTests.java",
    "chars": 11658,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/repository/config/MapRepositoryRegistrarWithFullDefaultingIntegrationTests.java",
    "chars": 2164,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/java/org/springframework/data/map/repository/config/MapRepositoryRegistrarWithTemplateDefinitionIntegrationTests.java",
    "chars": 2528,
    "preview": "/*\n * Copyright 2014-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "src/test/resources/logback.xml",
    "chars": 352,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration>\n\n\t<appender name=\"console\" class=\"ch.qos.logback.core.ConsoleAppe"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the spring-projects/spring-data-keyvalue GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 158 files (462.9 KB), approximately 114.7k tokens, and a symbol index with 1105 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!