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">
* @Persistent
* @Retention(RetentionPolicy.RUNTIME)
* @Target({ ElementType.TYPE })
* static @interface CacheCentricAnnotation {
*
* @AliasFor(annotation = KeySpace.class, attribute = "value")
* String cacheRegion() default "";
* }
*
* @CacheCentricAnnotation(cacheRegion = "customers")
* class Customer {
* // ...
* }
* </pre>
*
* Can also be directly used on types to indicate the keyspace.
*
* <pre class="code">
* @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
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
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.