From 25316d6183cf693230f2623ac5f1b975877b2233 Mon Sep 17 00:00:00 2001 From: Andrey G Date: Wed, 6 Dec 2023 16:32:20 +0200 Subject: [PATCH] FMWK-263 Update documentation (#661) --- README.adoc | 4 +- src/main/asciidoc/index.adoc | 8 +- src/main/asciidoc/preface.adoc | 4 +- .../reference/aerospike-object-mapping.adoc | 6 +- .../reference/aerospike-repositories.adoc | 22 +- src/main/asciidoc/reference/aerospike.adoc | 175 ----- .../reference/configure-data-settings.adoc | 103 +++ .../asciidoc/reference/functionality.adoc | 14 + .../asciidoc/reference/getting-started.adoc | 130 ---- .../reference/indexed-annotation.adoc | 2 + .../reference/installation-and-usage.adoc | 161 +++++ src/main/asciidoc/reference/introduction.adoc | 13 - .../asciidoc/reference/query-methods.adoc | 55 +- .../asciidoc/reference/scan-operation.adoc | 2 +- .../asciidoc/reference/secondary-indexes.adoc | 3 + src/main/asciidoc/reference/template.adoc | 21 +- .../object-mapping.adoc | 24 +- .../repositories.adoc | 20 +- .../data/aerospike/annotation/Indexed.java | 9 +- .../config/AerospikeDataSettings.java | 5 + .../aerospike/core/AerospikeOperations.java | 623 +++++++++--------- .../aerospike/core/AerospikeTemplate.java | 4 + .../core/ReactiveAerospikeOperations.java | 578 ++++++++-------- .../core/AerospikeTemplateDeleteTests.java | 2 +- .../core/AerospikeTemplateFindByIdTests.java | 14 +- .../core/AerospikeTemplateInsertTests.java | 8 +- .../core/AerospikeTemplateSaveTests.java | 65 +- .../core/AerospikeTemplateUpdateTests.java | 95 ++- ...veAerospikeTemplateDeleteRelatedTests.java | 7 +- ...tiveAerospikeTemplateSaveRelatedTests.java | 32 +- .../ReactiveAerospikeTemplateUpdateTests.java | 46 +- ...tiveIndexedPersonRepositoryQueryTests.java | 18 +- .../PersonRepositoryQueryTests.java | 38 +- .../aerospike/sample/PersonRepository.java | 7 - .../data/aerospike/sample/SampleClasses.java | 17 +- 35 files changed, 1175 insertions(+), 1160 deletions(-) delete mode 100644 src/main/asciidoc/reference/aerospike.adoc create mode 100644 src/main/asciidoc/reference/configure-data-settings.adoc create mode 100644 src/main/asciidoc/reference/functionality.adoc delete mode 100644 src/main/asciidoc/reference/getting-started.adoc create mode 100644 src/main/asciidoc/reference/installation-and-usage.adoc delete mode 100644 src/main/asciidoc/reference/introduction.adoc diff --git a/README.adoc b/README.adoc index efba0fe75..95ed04f6a 100644 --- a/README.adoc +++ b/README.adoc @@ -141,7 +141,7 @@ In order to configure Spring Data Aerospike you will need to create a configurat `AbstractAerospikeDataConfiguration`, defines the relevant Spring Data Repositories via `@EnableAerospikeRepositories` annotation and overrides `getHosts()` and `nameSpace()` methods with the required connection details. -You can optionally override other methods of `AbstractAerospikeDataConfiguration` to customize your configuration. +NOTE: You can optionally override xref:#configure-data-settings[`configureDataSettings`] method of `AbstractAerospikeDataConfiguration` to further customize your configuration. Here is a simple example of a configuration class that sets up a connection to a local Aerospike instance: @@ -213,7 +213,7 @@ Features supported by `AerospikeOperations`: * Basic support for mapping POJOs to and from Aerospike bins * Convenience CRUD (Create, Read, Update and Delete) methods for interacting with Aerospike -* Rich Query API +* Rich query API * Access to the native Aerospike Java Client (reactive and non-reactive) * Translating exceptions into Spring's https://docs.spring.io/spring/docs/current/spring-framework-reference/html/dao.html#dao-exceptions[technology-agnostic diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 47281578b..3243869d8 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -1,6 +1,6 @@ = Spring Data Aerospike - Documentation :doctype: book -:revnumber: 4.5.0 +:revnumber: 4.6.0 :revdate: {localdate} :toc: :toc-placement!: @@ -24,9 +24,8 @@ include::preface.adoc[] :leveloffset: +1 -include::reference/introduction.adoc[] -include::reference/aerospike.adoc[] -include::reference/getting-started.adoc[] +include::reference/functionality.adoc[] +include::reference/installation-and-usage.adoc[] include::spring-data-commons-docs/repositories.adoc[] include::reference/aerospike-repositories.adoc[] include::reference/aerospike-reactive-repositories.adoc[] @@ -40,6 +39,7 @@ include::reference/template.adoc[] include::reference/secondary-indexes.adoc[] include::reference/indexed-annotation.adoc[] include::reference/caching.adoc[] +include::reference/configure-data-settings.adoc[] include::spring-data-commons-docs/dependencies.adoc[] include::spring-data-commons-docs/auditing.adoc[] diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 240f8ad92..0fcfa46ba 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -26,9 +26,9 @@ The jumping off ground for learning about Aerospike is https://www.aerospike.com [[requirements]] == Requirements -Spring Data Aerospike binaries require JDK level 17.0 and above, and https://spring.io/docs[Spring Framework] 5.3.x and above. +Spring Data Aerospike binaries require JDK level 17.0 and above. -In terms of server, https://www.aerospike.com/download/server/[Aerospike] version at least 5.2 +In terms of server, it is required to use at least https://www.aerospike.com/download/server/[Aerospike server] version 5.2 (recommended to use the latest version when possible). == Additional Help Resources diff --git a/src/main/asciidoc/reference/aerospike-object-mapping.adoc b/src/main/asciidoc/reference/aerospike-object-mapping.adoc index 20c9d5bfb..213ef580b 100644 --- a/src/main/asciidoc/reference/aerospike-object-mapping.adoc +++ b/src/main/asciidoc/reference/aerospike-object-mapping.adoc @@ -1,4 +1,4 @@ -[[mapping-chapter]] +[[aerospike.object-mapping]] = Aerospike Object Mapping Rich mapping support is provided by the `AerospikeMappingConverter`. `AerospikeMappingConverter` has a rich metadata model that provides a full feature set of functionality to map domain objects to Aerospike clusters and objects.The mapping metadata model is populated using annotations on your domain objects. However, the infrastructure is not limited to using annotations as the only source of metadata information. The `AerospikeMappingConverter` also allows you to map objects without providing any additional metadata, by following a set of conventions. @@ -49,8 +49,8 @@ The following outlines what field will be mapped to the '_id' document field: The following outlines what type of conversion, if any, will be done on the property mapped to the _id document field. -* If a field named 'id' is declared as a String or BigInteger in the Java class it will be converted to and stored as a string. -* If no field named 'id' is present in the Java class then an implicit '_id' file will be generated by the driver but not mapped to a property or field of the Java class. +* By default, the type of the field annotated with `@id` is turned into a `String` to be stored in Aerospike database. If the original type cannot be persisted (see xref:#configure-data-settings.keep-original-key-types[keepOriginalKeyTypes] for details), it must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data. +* If no field named "id" is present in the Java class then an implicit '_id' file will be generated by the driver but not mapped to a property or field of the Java class. When querying and updating `AerospikeTemplate` will use the converter to handle conversions of the `Query` and `Update` objects that correspond to the above rules for saving documents so field names and types used in your queries will be able to match what is in your domain classes. diff --git a/src/main/asciidoc/reference/aerospike-repositories.adoc b/src/main/asciidoc/reference/aerospike-repositories.adoc index 83277246d..4f0574951 100644 --- a/src/main/asciidoc/reference/aerospike-repositories.adoc +++ b/src/main/asciidoc/reference/aerospike-repositories.adoc @@ -4,12 +4,17 @@ [[aerospike-repo-intro]] == Introduction -This chapter will point out the specialties for repository support for Aerospike. This builds on the <>, so make sure you've got a sound understanding of the basic concepts explained there. +One of the main goals of the Spring Data is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores. + +One of the core interfaces of Spring Data is `Repository`. +This interface acts primarily to capture the types to work with and to help user to discover interfaces that extend Repository. + +In other words, it allows user to have basic and complicated queries without writing the implementation. This builds on the <>, so make sure you've got a sound understanding of this concept. [[aerospike-repo-usage]] == Usage -To access domain entities stored in a Aerospike you can leverage our sophisticated repository support that eases implementing those quite significantly. To do so, simply create an interface for your repository: +To access entities stored in Aerospike you can leverage repository support that eases implementing those quite significantly. To do so, simply create an interface for your repository: .Sample Person entity ==== @@ -30,7 +35,7 @@ public class Person { } ---- ==== -We have a quite simple domain object here. The default serialization mechanism used in `AerospikeTemplate` (which is backing the repository support) regards properties named id as document id. Currently, we support`String` and `long` as id-types. +We have a quite simple domain object here. The default serialization mechanism used in `AerospikeTemplate` (which is backing the repository support) regards properties named "id" as document id. Currently we support `String` and `long` as id-types. .Basic repository interface to persist Person entities ==== @@ -46,7 +51,7 @@ public interface PersonRepository extends AerospikeRepository { ---- ==== -Right now this interface simply serves typing purposes but we will add additional methods to it later. In your Spring configuration simply add +Right now this interface simply serves typing purposes, but we will add additional methods to it later. In your Spring configuration simply add .General Aerospike repository Spring configuration ==== @@ -142,8 +147,8 @@ public interface PersonRepository extends PagingAndSortingRepository The method shows a query for all people with the given name. The query will be derived by parsing the method name for constraints that can be concatenated with `And` and `Or`. -<2> Applies pagination to a query. Just equip your method signature with a `Pageable` parameter and let the method return a `Page` instance and we will automatically page the query accordingly. -<3> Shows that you can query-based partial name searches. +<2> Applies pagination to a query. Just equip your method signature with a `Pageable` parameter and let the method return a `Page` instance, and it will automatically page the query accordingly (i.e. return the required part of results). +<3> Uses query-based partial name search. ==== [[aerospike.repositories.example]] @@ -160,9 +165,6 @@ public class RepositoryExample { @Autowired AerospikeClient client; - /** - * @param ctx - */ public RepositoryExample(ApplicationContext ctx) { aerospikeOperations = ctx.getBean(AerospikeTemplate.class); repository = (PersonRepository) ctx.getBean("personRepository"); @@ -196,7 +198,7 @@ public class RepositoryExample { for (Person person : result) { System.out.println(person.toString()); } - System.out.println("Results for name startting with letter 'M'"); + System.out.println("Results for name starting with letter 'M'"); List resultPartial = repository.findByNameStartsWith("M"); for (Person person : resultPartial) { System.out.println(person.toString()); diff --git a/src/main/asciidoc/reference/aerospike.adoc b/src/main/asciidoc/reference/aerospike.adoc deleted file mode 100644 index 359a793db..000000000 --- a/src/main/asciidoc/reference/aerospike.adoc +++ /dev/null @@ -1,175 +0,0 @@ -[[aerospike.functionality]] -= Aerospike Functionality - -Aerospike supports a wide range of features summarized below: - -* Feature Rich Object Mapping integrated with Spring's Conversion Service -* Automatic implementation of Repository interfaces including support for custom finder methods -* AerospikeTemplate helper class for performing common Aerospike operations -* Exceptions translation into Spring's portable Data Access Exception hierarchy -* Annotation-based mapping metadata but extensible to support other metadata formats - -[[aerospike-getting-started]] -== Getting Started - -Spring Data Aerospike uses Java Client, Aerospike’s Java client enables you to build applications in Java that store and retrieve data from an Aerospike cluster. It contains both synchronous and asynchronous calls to the database. - -The Java Client runs on any platform with Java 1.8 version and above. - -First, you need to set up a running Aerospike server. - -To create a Spring project in STS go to File -> New -> Spring Template Project -> Simple Spring Utility Project -> press Yes when prompted. Then enter a project and a package name such as org.spring.aerospike.example. - -Then add the following to `pom.xml` dependencies section. - -[source,xml] ----- - - - - - - com.aerospike - spring-data-aerospike - 4.5.0 - - - ----- - -You can either set up Spring Boot or Spring application. Basic setup of Spring Boot application is described under the following link: https://projects.spring.io/spring-boot. - -.Spring Boot compatibility -[width="100%",cols="<24%,<14%,<18%,<26%,<18%",options="header",] -|=== -|Spring Data Aerospike |Spring Boot |Aerospike Client |Aerospike Reactor Client |Aerospike Server -|4.5.x |3.1.x |7.1.x |7.0.x |5.2.x.x + - -|4.4.x |3.1.x |7.0.x |7.0.x |5.2.x.x + - -|4.3.x |3.1.x |6.1.x |6.1.x |5.2.x.x + - -|4.2.x |3.0.x |6.1.x |6.1.x |5.2.x.x + - -|4.1.x |3.0.x |6.1.x |6.1.x |5.2.x.x + - -|3.5.x |2.7.x |6.1.x |6.1.x |5.2.x.x + - -|3.4.x |2.6.x |5.1.x |5.1.x |5.2.x.x + - -|3.3.x |2.5.x |5.1.x |5.1.x |5.2.x.x + - -|3.2.x |2.5.x |5.1.x |5.0.x |5.2.x.x + - -|3.0.x, 3.1.x |2.5.x |5.1.x |5.0.x | - -|2.5.x |2.5.x |4.4.x |4.4.x | - -|2.4.2.RELEASE |2.3.x |4.4.x |4.4.x | - -|2.3.5.RELEASE |2.2.x |4.4.x |4.4.x | - -|2.1.1.RELEASE |2.1.x, 2.0.x |4.4.x |3.2.x | - -|1.2.1.RELEASE |1.5.x |4.1.x | | -|=== - -In case you do not want to use Spring Boot, the best way to manage Spring dependencies is to declare `spring-framework-bom` of the needed version in the `dependencyManagement` section of your `pom.xml`: - -[source,xml] ----- - - - - org.springframework - spring-framework-bom - ${place Spring version here} - pom - import - - - ----- - -Create a simple Person class to persist. - -[source,java] ----- -package org.springframework.data.aerospike.example; - -public class Person { - - public final String id; - public final String name; - public final int age; - - public Person(String id, String name, int age) { - this.id = id; - this.name = name; - this.age = age; - } - - @Override - public String toString() { - return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; - } -} ----- - -In the simplest case, your repository will extend the AerospikeRepository, where T is the entity that you want to expose. - -[source,java] ----- -package org.springframework.data.aerospike.example.repo; - -import org.springframework.data.aerospike.repository.AerospikeRepository; - -public interface PersonRepository extends AerospikeRepository { -} ----- -Please note that this is just an interface and not an actual class. In the background, when your context gets initialized, actual implementations for your repository descriptions get created and you can access them through regular beans. -This means you will save lots of boilerplate code while still exposing full CRUD semantics to your service layer and application. - -To setup configuration for Aerospike you will need to subclass `AbstractAerospikeDataConfiguration`: - -[source,java] ----- -package org.springframework.data.aerospike.example.config; - -import com.aerospike.client.Host; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.aerospike.repository.config.EnableAerospikeRepositories; -import org.springframework.data.aerospike.example.repo.PersonRepository; - -import java.util.Collection; -import java.util.Collections; - -@Configuration -@EnableAerospikeRepositories(basePackageClasses = PersonRepository.class) -public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration { - - @Override - protected Collection getHosts() { - return Collections.singleton(new Host("localhost", 3000)); - } - - @Override - protected String nameSpace() { - return "SAMPLE"; - } -} ----- - -Now you are ready to inject and use `PersonRepository` in your application. - -[[aerospike.auditing]] -== General auditing configuration - -Auditing support is not available in the current version. - -[[aerospike-template-intro]] -== Introduction to AerospikeTemplate - -The template provides lower-level access to the database and also serves as the foundation for repositories. -For more information see xref:#aerospike.template[AerospikeTemplate] for more information. - diff --git a/src/main/asciidoc/reference/configure-data-settings.adoc b/src/main/asciidoc/reference/configure-data-settings.adoc new file mode 100644 index 000000000..4fdf6323f --- /dev/null +++ b/src/main/asciidoc/reference/configure-data-settings.adoc @@ -0,0 +1,103 @@ +[[configure-data-settings]] += Configure Data Settings + +The `AbstractAerospikeDataConfiguration` class exposes a number of beans that Spring Data Aerospike uses internally. User can optionally override `configureDataSettings` method to customize configuration. + +Here is an example: + +[source,java] +---- +@EnableAerospikeRepositories(basePackageClasses = PersonRepository.class) +class ApplicationConfig extends AbstractAerospikeDataConfiguration { + + @Override + protected Collection getHosts() { + return Collections.singleton(new Host("localhost", 3000)); + } + + @Override + protected String nameSpace() { + return "test"; + } + + @Override + protected void configureDataSettings(AerospikeDataSettings.AerospikeDataSettingsBuilder builder) { + builder.createIndexesOnStartup(true); + builder.indexCacheRefreshFrequencySeconds(3600); + builder.queryMaxRecords(10000L); + } +} +---- + +[[configure-data-settings.parameters]] +== Configuration Parameters + +[[configure-data-settings.scans-enabled]] +=== scansEnabled + +A scan can be an expensive operation as all records in the set must be read by the Aerospike server, and then the condition is applied to see if they match. + +Due to the cost of performing this operation, scans from Spring Data Aerospike are disabled by default. + +NOTE: Once this flag is enabled, scans run whenever needed with no warnings. This may or may not be optimal in a particular use case. + +*Default:* `false`. + +[[configure-data-settings.send-key]] +=== sendKey + +Send user defined key in addition to hash digest on both reads and writes. If the key is sent on write, it will be stored with the record on the server. + +Default: `false` (do not send the user defined key). + +[[configure-data-settings.create-indexes-on-startup]] +=== createIndexesOnStartup + +Create secondary indexes specified using `@Indexed` annotation on startup. + +*Default*: `true`. + +[[configure-data-settings.index-cache-refresh-frequency-seconds]] +=== indexCacheRefreshFrequencySeconds + +Automatically refresh indexes cache every seconds. + +*Default*: `3600`. + +[[configure-data-settings.query-max-records]] +=== queryMaxRecords + +Limit amount of results returned by server. Non-positive value means no limit. + +*Default*: `10 000`. + +[[configure-data-settings.keep-original-key-types]] +=== keepOriginalKeyTypes + +Define how `@Id` fields (primary keys) and `Map` keys are stored in the Aerospike database: `false` - always as `String`, `true` - preserve original type if supported. + +[width="100%",cols="<20%,<30%,<30%",options="header",] +|=== +|`@Id` field type |keepOriginalKeyTypes = `false` |keepOriginalKeyTypes = `true` +|`long` |`String` | `long` +|`int` |`String` | `long` +|`String` |`String` | `String` +|`byte[]` |`String` | `byte[]` +|other types |`String` | `String` +|=== + +NOTE: If `@Id` field's type cannot be persisted as is, it must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data. + +[width="100%",cols="<20%,<30%,<30%",options="header",] +|=== +|`Map` key type |keepOriginalKeyTypes = `false` |keepOriginalKeyTypes = `true` +|`long` |`String` | `long` +|`int` |`String` | `long` +|`double` |`String` | `double` +|`String` |`String` | `String` +|`byte[]` |`String` | `byte[]` +|other types |`String` | `String` +|=== + +*Default*: `false` (store keys only as `String`). + diff --git a/src/main/asciidoc/reference/functionality.adoc b/src/main/asciidoc/reference/functionality.adoc new file mode 100644 index 000000000..ebb31cd6c --- /dev/null +++ b/src/main/asciidoc/reference/functionality.adoc @@ -0,0 +1,14 @@ +[[aerospike.functionality]] += Functionality + +https://github.com/aerospike/spring-data-aerospike[Spring Data Aerospike project] aims to provide a familiar and consistent Spring-based programming model providing integration with the Aerospike database. + +Spring Data Aerospike supports a wide range of features summarized below: + +* Supporting Repository interfaces (out-of-the-box CRUD operations and query implementations, for more information see xref:#aerospike.repositories[Aerospike Repositories]) +* AerospikeTemplate for lower-level access to common Aerospike operations and fine-tuning (for more information see xref:#aerospike.template[AerospikeTemplate]) +* xref:#aerospike.object-mapping[Feature Rich Object Mapping] integrated with Spring's Conversion Service +* Translating exceptions into Spring's https://docs.spring.io/spring/docs/current/spring-framework-reference/html/dao.html#dao-exceptions[Data Access Exception hierarchy] +* Annotation-based metadata mapping +* Ability to directly utilize Aerospike Java client functionality + diff --git a/src/main/asciidoc/reference/getting-started.adoc b/src/main/asciidoc/reference/getting-started.adoc deleted file mode 100644 index 589801030..000000000 --- a/src/main/asciidoc/reference/getting-started.adoc +++ /dev/null @@ -1,130 +0,0 @@ -= Installation & Usage - -== Getting Started - -To use Spring Data Aerospike in your project, the first step is to add it to your build process. For Maven, this is as simple as: - -[source, xml] ----- - - com.aerospike - spring-data-aerospike - 4.5.0 - ----- - -For Gradle: - -[source, text] ----- -implementation group: 'com.aerospike', name: 'spring-data-aerospike', version: '4.5.0' ----- - -== Connecting to Aerospike DB - -Connecting to the repository is easy with the help of the `AbstractAerospikeDataConfiguration` class. - -[source, java] ----- -@Configuration -@EnableAerospikeRepositories(basePackageClasses = { PersonRepository.class}) -public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration { - @Override - protected Collection getHosts() { - return Collections.singleton(new Host("localhost", 3000)); - } - - @Override - protected String nameSpace() { - return "test"; - } -} ----- - -`@Configuration` tells Spring that this class contains configuration data, and `@EnableAerospikeRepositories` activates Aerospike repositories that can be used for data access. The parameter to this annotation tells Spring Data Aerospike where to look for the repositories. This can be a list of package names as strings using the `basePackages` value, or a list of classes through the `basePackageClass` value. If the latter is used (as in this example), the class is used to determine which package to scan, and all repositories in that package will be available for use. More details on repositories are below. - -The `AbstractAerospikeDataConfiguration` class exposes a number of beans that Spring Data Aerospike uses internally. Some of these, in particular the `AerospikeTemplate` bean, are useful in their own right if finer-grained control over data access is needed. The primary information required by this configuration is how to connect to the cluster, provided through the `getHosts` and `nameSpace` calls. - -== Creating Functionality - -The base functionality for using Spring Data is provided by the AerospikeRepository interface. This typically takes 2 parameters: - -[arabic] -. The type which this class manages is typically an entity class to be stored in the database. -. The type of ID for this class. - -Application code typically extends this interface for each of the types to be managed, and methods can be added to the interface to determine how the application can access the data. For example, consider a class `Person` with a simple structure: - -[source, java] ----- -@AllArgsConstructor -@NoArgsConstructor -@Data -@Document -public class Person { - @Id - private long id; - private String firstName; - private String lastName; - @Field("dob") - private Date dateOfBirth; -} ----- - -Note that this example uses the https://projectlombok.org/[Project Lombok] annotations to remove the need for explicit constructors and getters and setters. Normal POJOs which define these on their own can ignore the `@AllArgsConstructor`, `@NoArgsConstructor` and `@Data` annotations. The `@Document` annotation tells Spring Data Aerospike that this is a domain object to be persisted in the database, and `@Id` identifies the primary key of this class. The `@Field` annotation is used to create a shorter name for the bin in the Aerospike database (`dateOfBirth` will be stored in a bin called `dob` in this example). - -For the `Person` object to be persisted to Aerospike, you must create an interface with the desired methods for retrieving data. For example: - -[source, java] ----- -public interface PersonRepository extends AerospikeRepository { - public List findByLastName(String lastName); -} ----- - -This defines a repository that can write `Person` entities as well as being able to query people by last name. The `AerospikeRepository` extends both `PagingAndSortingRepository` and `CrudRepository` so methods like `count()`, `findById()`, `save()` and `delete()` are there by default. For reactive users, use the `ReactiveAerospikeRepository` instead. - -Note that this is just an interface and not an actual class. In the background, when your context gets initialized, actual implementations for your repository descriptions get created and you can access them through regular beans. This means you will save lots of boilerplate code while still exposing full CRUD semantics to your service layer and application. - -Once this is defined, the repository is ready for use. A sample Spring Controller which uses this repository could be: - -[source, java] ----- -@RestController -public class ApplicationController { - @Autowired - private PersonRepository personRepsitory; - - @GetMapping("/seed") - public int seedData() { - Person person = new Person(1, "Bob", "Jones", new GregorianCalendar(1971, 12, 19).getTime()); - personRepsitory.save(person); - return 1; - } - - @GetMapping("/findByLastName/{lastName}") - public List findByLastName(@PathVariable(name = "lastName", required=true) String lastName) { - return personRepsitory.findByLastName(lastName); - } -} ----- - -Invoking the `seed` method above gives you a record in the Aerospike database which looks like: - -[source, text] ----- -aql> select * from test.Person where pk = "1" -+-----+-----------+----------+-------------+-------------------------------------+ -| PK | firstName | lastName | dob | @_class | -+-----+-----------+----------+-------------+-------------------------------------+ -| "1" | "Bob" | "Jones" | 64652400000 | "com.aerospike.sample.model.Person" | -+-----+-----------+----------+-------------+-------------------------------------+ -1 row in set (0.001 secs) ----- - -There are 2 important things to notice here: - -[arabic] -. The fully qualified path of the class is listed in each record. This is needed to instantiate the class correctly, especially in cases where the compile-time type and runtime type of the object differ. For example, where a field is declared as a super class but the instantiated class is a subclass. -. The `long` id field was turned into a `String` when stored in the database. All `@Id` fields must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using an external tool like `AQL` to view the data. - diff --git a/src/main/asciidoc/reference/indexed-annotation.adoc b/src/main/asciidoc/reference/indexed-annotation.adoc index 0269aa51b..838883a96 100644 --- a/src/main/asciidoc/reference/indexed-annotation.adoc +++ b/src/main/asciidoc/reference/indexed-annotation.adoc @@ -148,3 +148,5 @@ So the following will be true: |a.dd.[1].{#0} |[mapKey("a"), mapKey("dd"),listIndex(1), mapRank(0)] |y |=== +NOTE: There are relevant configuration parameters in AerospikeDataSettings: +xref:#configure-data-settings.create-indexes-on-startup[create indexes on startup] and xref:#configure-data-settings.index-cache-refresh-frequency-seconds[indexes cache refresh frequency]. diff --git a/src/main/asciidoc/reference/installation-and-usage.adoc b/src/main/asciidoc/reference/installation-and-usage.adoc new file mode 100644 index 000000000..0af6ef3cd --- /dev/null +++ b/src/main/asciidoc/reference/installation-and-usage.adoc @@ -0,0 +1,161 @@ +[[aerospike.installation_and_usage]] += Installation & Usage + +== Getting Started + +First, you need a running https://docs.aerospike.com/server/operations/install/verify[Aerospike server] to connect to. + +To use Spring Data Aerospike you can either set up Spring Boot or Spring application. Basic setup of Spring Boot application is described here: https://projects.spring.io/spring-boot. + +In case you do not want to use Spring Boot, the best way to manage Spring dependencies is to declare `spring-framework-bom` of the needed version in the `dependencyManagement` section of your `pom.xml`: + +[source,xml] +---- + + + + org.springframework + spring-framework-bom + ${spring-data-aerospike.version} + pom + import + + + +---- + +NOTE: To create a Spring project in STS (Spring Tool Suite) go to File -> New -> Spring Template Project -> Simple Spring Utility Project -> press "Yes" when prompted. Then enter a project and a package name such as `org.spring.aerospike.example`. + +== Adding Dependency + +The first step is to add Spring Data Aerospike to your build process. It is recommended to use the latest version which can be found on the https://github.com/aerospike/spring-data-aerospike/releases[GitHub Releases] page. + +Adding Spring Data Aerospike dependency in Maven: + +[source, xml] +---- + + com.aerospike + spring-data-aerospike + ${spring-data-aerospike.version} + +---- + +Adding Spring Data Aerospike dependency in Gradle: + +[source, text] +---- +implementation group: 'com.aerospike', name: 'spring-data-aerospike', version: '${spring-data-aerospike.version}' +---- + +== Connecting to Aerospike DB + +Configuring Spring Data Aerospike is easy with the help of the `AbstractAerospikeDataConfiguration` class. + +[source, java] +---- +@Configuration +@EnableAerospikeRepositories(basePackageClasses = { PersonRepository.class}) +public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration { + @Override + protected Collection getHosts() { + return Collections.singleton(new Host("localhost", 3000)); + } + + @Override + protected String nameSpace() { + return "test"; + } +} +---- + +`@Configuration` tells Spring that this class contains configuration data, and `@EnableAerospikeRepositories` activates Aerospike repositories that can be used for data access. The parameter to this annotation tells Spring Data Aerospike where to look for the repositories. This can be a list of package names as strings using the `basePackages` value, or a list of classes through the `basePackageClass` value. If the latter is used (as in this example), the class is used to determine which package to scan, and all repositories in that package will be available for use. More details on repositories are below. + +The primary information required by this configuration is how to connect to the cluster, provided through the `getHosts` and `nameSpace` calls. + +NOTE: You can optionally override xref:#configure-data-settings[`configureDataSettings`] method of `AbstractAerospikeDataConfiguration` to customize your configuration. + +== Creating Functionality + +The base functionality is provided by `AerospikeRepository` interface. + +It typically takes 2 parameters: + +[arabic] +. The type managed by a class (it is typically entity class) to be stored in the database. +. The type of ID. + +Application code typically extends this interface for each of the types to be managed, and methods can be added to the interface to determine how the application can access the data. For example, consider a class `Person` with a simple structure: + +[source, java] +---- +@AllArgsConstructor +@NoArgsConstructor +@Data +@Document +public class Person { + @Id + private long id; + private String firstName; + private String lastName; + @Field("dob") + private Date dateOfBirth; +} +---- + +Note that this example uses the https://projectlombok.org/[Project Lombok] annotations to remove the need for explicit constructors and getters and setters. Normal POJOs which define these on their own can ignore the `@AllArgsConstructor`, `@NoArgsConstructor` and `@Data` annotations. The `@Document` annotation tells Spring Data Aerospike that this is a domain object to be persisted in the database, and `@Id` identifies the primary key of this class. The `@Field` annotation is used to create a shorter name for the bin in the Aerospike database (`dateOfBirth` will be stored in a bin called `dob` in this example). + +For the `Person` object to be persisted to Aerospike, you must create an interface with the desired methods for retrieving data. For example: + +[source, java] +---- +public interface PersonRepository extends AerospikeRepository { + List findByLastName(String lastName); +} +---- + +This defines a repository that can write `Person` entities and also query them by last name. The `AerospikeRepository` extends both `PagingAndSortingRepository` and `CrudRepository`, so methods like `count()`, `findById()`, `save()` and `delete()` are there by default. Those who need reactive flow can use `ReactiveAerospikeRepository` instead. + +NOTE: Repository is just an interface and not an actual class. In the background, when your context gets initialized, actual implementations for your repository descriptions get created, and you can access them through regular beans. This means you will omit lots of boilerplate code while still exposing full CRUD semantics to your service layer and application. + +Example repository is ready for use. A sample Spring Controller which uses this repository could be the following: + +[source, java] +---- +@RestController +public class ApplicationController { + @Autowired + private PersonRepository personRepsitory; + + @GetMapping("/seed") + public int seedData() { + Person person = new Person(1, "Bob", "Jones", new GregorianCalendar(1971, 12, 19).getTime()); + personRepsitory.save(person); + return 1; + } + + @GetMapping("/findByLastName/{lastName}") + public List findByLastName(@PathVariable(name = "lastName", required=true) String lastName) { + return personRepsitory.findByLastName(lastName); + } +} +---- + +Invoking the `seed` method above gives you a record in the Aerospike database which looks like: + +[source, text] +---- +aql> select * from test.Person where pk = "1" ++-----+-----------+----------+-------------+-------------------------------------+ +| PK | firstName | lastName | dob | @_class | ++-----+-----------+----------+-------------+-------------------------------------+ +| "1" | "Bob" | "Jones" | 64652400000 | "com.aerospike.sample.model.Person" | ++-----+-----------+----------+-------------+-------------------------------------+ +1 row in set (0.001 secs) +---- + +NOTE: The fully qualified path of the class is listed in each record. This is needed to instantiate the class correctly, especially in cases when the compile-time type and runtime type of the object differ. For example, where a field is declared as a super class but the instantiated class is a subclass. + +NOTE: By default, the type of the field annotated with `@id` is turned into a `String` to be stored in Aerospike database. If the original type cannot be persisted (see xref:#configure-data-settings.keep-original-key-types[keepOriginalKeyTypes] for details), it must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data. + + diff --git a/src/main/asciidoc/reference/introduction.adoc b/src/main/asciidoc/reference/introduction.adoc deleted file mode 100644 index 6fe51d684..000000000 --- a/src/main/asciidoc/reference/introduction.adoc +++ /dev/null @@ -1,13 +0,0 @@ -[[introduction]] -= Introduction - -== Document Structure - -This part of the reference documentation contains links to the core functionality offered by Spring Data Aerospike. - -- Aerospike feature set: <> - -- Repository functionality: <> - -- Template functionality: <> - diff --git a/src/main/asciidoc/reference/query-methods.adoc b/src/main/asciidoc/reference/query-methods.adoc index 015c5ec01..c470cf00e 100644 --- a/src/main/asciidoc/reference/query-methods.adoc +++ b/src/main/asciidoc/reference/query-methods.adoc @@ -84,19 +84,21 @@ findByObjectFieldIsNull() |True |findByEnabledTrue() |...where x.enabled = true |False |findByOptOutFalse() |...where x.optOut = false + +|FindUsingQuery |findUsingQuery(query) |find matching entities (see xref:#find-using-query[find using query]]) |=== -An example of an interface with several query methods is: +Below is an example of an interface with several query methods: -[source, java] +[source,java] ---- public interface PersonRepository extends AerospikeRepository { - public List findByLastName(String lastName); - public List findByLastNameContaining(String lastName); - public List findByLastNameStartingWith(String lastName); - public List findByLastNameAndFirstNameContaining(String lastName, String firstName); - public List findByAgeBetween(long startAge, long endAge); - public Optional findById(Long id); + List findByLastName(String lastName); + List findByLastNameContaining(String lastName); + List findByLastNameStartingWith(String lastName); + List findByLastNameAndFirstNameContaining(String lastName, String firstName); + List findByAgeBetween(long startAge, long endAge); + Optional findById(Long id); } ---- @@ -114,3 +116,40 @@ public interface PersonRepository extends AerospikeRepository { |Distinct | findDistinctByFirstNameContaining | select distinct ... where x.firstName like 'abc%' |=== + +[[find-using-query]] +== Find Using Query + +User can perform a custom `Query` for finding matching entities in the Aerospike database. A `Query` can be created using a `Qualifier` which represents an expression. It may contain other qualifiers and combine them using either `AND` or `OR`. + +`Qualifier` can be created for regular bins, metadata and ids (primary keys). Below is an example of different variations: + +[source,java] +---- + // creating an expression "firsName is equal to John" + Qualifier firstNameEqJohn = Qualifier.builder() + .setField("firstName") + .setFilterOperation(FilterOperation.EQ) + .setValue1(Value.get("John")) + .build(); + result = repository.findUsingQuery(new Query(firstNameEqJohn)); + assertThat(result).containsOnly(john); + + // creating an expression "primary key is equal to person's id" + Qualifier keyEqJohnsId = Qualifier.idEquals(john.getId()); + result = repository.findUsingQuery(new Query(keyEqJohnsId)); + assertThat(result).containsOnly(john); + + // creating an expression "since_update_time metadata value is less than 50 seconds" + Qualifier sinceUpdateTimeLt50Seconds = Qualifier.metadataBuilder() + .setMetadataField(SINCE_UPDATE_TIME) + .setFilterOperation(FilterOperation.LT) + .setValue1AsObj(50000L) + .build(); + result = repository.findUsingQuery(new Query(sinceUpdateTimeLt50Seconds)); + assertThat(result).contains(john); + + // expressions are combined using AND + result = repository.findUsingQuery(new Query(Qualifier.and(firstNameEqJohn, keyEqJohnsId, sinceUpdateTimeLt50Seconds))); + assertThat(result).containsOnly(john); +---- \ No newline at end of file diff --git a/src/main/asciidoc/reference/scan-operation.adoc b/src/main/asciidoc/reference/scan-operation.adoc index 99232a983..22371ae53 100644 --- a/src/main/asciidoc/reference/scan-operation.adoc +++ b/src/main/asciidoc/reference/scan-operation.adoc @@ -7,7 +7,7 @@ Due to the cost of performing this operation, scans from Spring Data Aerospike a == Enabling Scan -If the cost of the scans is acceptable to an organization, they can be enabled by setting `scansEnabled` to `true` in `AerospikeDataSettings`. +If the cost of the scans is acceptable to an organization, they can be enabled by setting xref:#configure-data-settings.scans-enabled[`scansEnabled`] to `true` in `AerospikeDataSettings`. One way to do this is to create a custom bean which overrides the default settings: diff --git a/src/main/asciidoc/reference/secondary-indexes.adoc b/src/main/asciidoc/reference/secondary-indexes.adoc index 38b7d5ec7..bba594078 100644 --- a/src/main/asciidoc/reference/secondary-indexes.adoc +++ b/src/main/asciidoc/reference/secondary-indexes.adoc @@ -125,3 +125,6 @@ public List findByFirstName(String firstName); In this case `firstName` is not marked as `@Indexed`, so SpringData Aerospike is not instructed to create an index on it. Hence, it will scan the repository (a costly operation that could be avoided by using an index). +NOTE: There are relevant configuration parameters in AerospikeDataSettings: +xref:#configure-data-settings.create-indexes-on-startup[create indexes on startup] and xref:#configure-data-settings.index-cache-refresh-frequency-seconds[indexes cache refresh frequency]. + diff --git a/src/main/asciidoc/reference/template.adoc b/src/main/asciidoc/reference/template.adoc index c532dbe71..8785e5fb8 100644 --- a/src/main/asciidoc/reference/template.adoc +++ b/src/main/asciidoc/reference/template.adoc @@ -7,9 +7,9 @@ It allows lower-level access than a Repository and also serves as the foundation Template is the central support class for Aerospike database operations. It provides the following functionality: -- Mapping between Java objects and Aerospike Bins (see Mapping) - Methods to interact with the database -- Connection callback +- Mapping between Java objects and Aerospike Bins (see <>) +- Providing connection callback - Translating exceptions into Spring's technology-agnostic https://docs.spring.io/spring/docs/current/spring-framework-reference/html/dao.html#dao-exceptions[DAO exceptions hierarchy] [[aerospike-template.instantiating]] @@ -33,8 +33,7 @@ For CAS updates `save` operation must be used. `AerospikeOperations` interface provides operations for interacting with the database (`exists`, `find`, `insert`, `update` etc.) as well as basic operations with indexes: `createIndex`, `deleteIndex`, `indexExists`. -The names of operations are typically self-descriptive. -To read from Aerospike you can use `findById`, `findByIds` and `find` methods, to delete - `delete` methods, and so on. +The names of operations are typically self-descriptive. To read from Aerospike you can use `findById`, `findByIds` and `find` methods, to delete - `delete` methods, and so on. [source,java] ---- @@ -73,13 +72,13 @@ template.insert(new Person(id, "John", 50)); long count = template.count (new Query - (new QualifierBuilder() - .setFilterOperation(FilterOperation.EQ) - .setField("firstName") - .setValue1(Value.get("John")) - .build() - ), - Person.class + (new QualifierBuilder() + .setFilterOperation(FilterOperation.EQ) + .setField("firstName") + .setValue1(Value.get("John")) + .build() + ), + Person.class ); assertThat(count).isEqualTo(3); diff --git a/src/main/asciidoc/spring-data-commons-docs/object-mapping.adoc b/src/main/asciidoc/spring-data-commons-docs/object-mapping.adoc index c2213c3ac..6a9ee1e23 100644 --- a/src/main/asciidoc/spring-data-commons-docs/object-mapping.adoc +++ b/src/main/asciidoc/spring-data-commons-docs/object-mapping.adoc @@ -46,7 +46,7 @@ class Person { we will create a factory class semantically equivalent to this one at runtime: -[source, java] +[source,java] ---- class PersonObjectInstantiator implements ObjectInstantiator { @@ -114,7 +114,7 @@ class Person { .A generated Property Accessor ==== -[source, java] +[source,java] ---- class PersonPropertyAccessor implements PersistentPropertyAccessor { @@ -136,9 +136,14 @@ class PersonPropertyAccessor implements PersistentPropertyAccessor { } } ---- -<1> PropertyAccessor's hold a mutable instance of the underlying object. This is, to enable mutations of otherwise immutable properties. -<2> By default, Spring Data uses field-access to read and write property values. As per visibility rules of `private` fields, `MethodHandles` are used to interact with fields. -<3> The class exposes a `withId(…)` method that's used to set the identifier, e.g. when an instance is inserted into the datastore and an identifier has been generated. Calling `withId(…)` creates a new `Person` object. All subsequent mutations will take place in the new instance leaving the previous untouched. + +<1> PropertyAccessor's hold a mutable instance of the underlying object. +This is, to enable mutations of otherwise immutable properties. +<2> By default, Spring Data uses field-access to read and write property values. +As per visibility rules of `private` fields, `MethodHandles` are used to interact with fields. +<3> The class exposes a `withId(…)` method that's used to set the identifier, e.g. when an instance is inserted into the datastore and an identifier has been generated. +Calling `withId(…)` creates a new `Person` object. +All subsequent mutations will take place in the new instance leaving the previous untouched. <4> Using property-access allows direct method invocations without using `MethodHandles`. ==== @@ -148,7 +153,8 @@ For the domain class to be eligible for such optimization, it needs to adhere to - Types must not reside in the default or under the `java` package. - Types and their constructors must be `public` - Types that are inner classes must be `static`. -- The used Java Runtime must allow for declaring classes in the originating `ClassLoader`. Java 9 and newer impose certain limitations. +- The used Java Runtime must allow for declaring classes in the originating `ClassLoader`. +Java 9 and newer impose certain limitations. By default, Spring Data attempts to use generated property accessors and falls back to reflection-based ones if a limitation is detected. **** @@ -157,7 +163,7 @@ Let's have a look at the following entity: .A sample entity ==== -[source, java] +[source,java] ---- class Person { @@ -194,6 +200,7 @@ class Person { } ---- ==== + <1> The identifier property is final but set to `null` in the constructor. The class exposes a `withId(…)` method that's used to set the identifier, e.g. when an instance is inserted into the datastore and an identifier has been generated. The original `Person` instance stays unchanged as a new one is created. @@ -424,7 +431,7 @@ public final class SubType extends SuperType { Getters and setters on `SubType` set only `SubType.field` and not `SuperType.field`. In such an arrangement, using the constructor is the only default approach to set `SuperType.field`. -Adding a method to `SubType` to set `SuperType.field` via `this.SuperType.field = …` is possible but falls outside of supported conventions. +Adding a method to `SubType` to set `SuperType.field` via `this.SuperType.field = …` is possible but falls outside supported conventions. Property overrides create conflicts to some degree because the properties share the same name yet might represent two distinct values. We generally recommend using distinct property names. @@ -436,3 +443,4 @@ You can exclude properties by annotating these with `@Transient`. 2. How to represent properties in your data store? Using the same field/column name for different values typically leads to corrupt data so you should annotate least one of the properties using an explicit field/column name. 3. Using `@AccessType(PROPERTY)` cannot be used as the super-property cannot be set. + diff --git a/src/main/asciidoc/spring-data-commons-docs/repositories.adoc b/src/main/asciidoc/spring-data-commons-docs/repositories.adoc index d8ddca7f5..ecb7602f9 100644 --- a/src/main/asciidoc/spring-data-commons-docs/repositories.adoc +++ b/src/main/asciidoc/spring-data-commons-docs/repositories.adoc @@ -12,8 +12,6 @@ The goal of the Spring Data repository abstraction is to significantly reduce th [IMPORTANT] ==== -_Spring Data repository documentation and your module_ - This chapter explains the core concepts and interfaces of Spring Data repositories. The information in this chapter is pulled from the Spring Data Commons module. It uses the configuration and code samples for the Jakarta Persistence API (JPA) module. @@ -32,6 +30,8 @@ It takes the domain class to manage as well as the identifier type of the domain This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one. The https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html[`CrudRepository`] and https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/ListCrudRepository.html[`ListCrudRepository`] interfaces provide sophisticated CRUD functionality for the entity class that is being managed. +NOTE: "Entity" or "document" are the terms often used in Spring Data Aerospike interchangeably to describe a domain object - a Java object that identifies Aerospike DB record. + [[repositories.repository]] .`CrudRepository` Interface ==== @@ -39,7 +39,7 @@ The https://docs.spring.io/spring-data/commons/docs/current/api/org/springframew ---- public interface CrudRepository extends Repository { - S save(S entity); <1> + S save(S document); <1> Optional findById(ID primaryKey); <2> @@ -54,12 +54,12 @@ public interface CrudRepository extends Repository { // … more functionality omitted. } ---- -<1> Saves the given entity. -<2> Returns the entity identified by the given ID. -<3> Returns all entities. -<4> Returns the number of entities. -<5> Deletes the given entity. -<6> Indicates whether an entity with the given ID exists. +<1> Saves the given document of type `T`. +<2> Returns the DB record identified by the given ID, the record is mapped to a document of type `T`. +<3> Returns all DB records from the associated set mapped to documents of type `T`. +<4> Returns the number of all DB records in the associated set. +<5> Deletes a particular DB record using a document to identify it. +<6> Indicates whether a DB record with the given ID exists. ==== The methods declared in this interface are commonly referred to as CRUD methods. @@ -1144,7 +1144,7 @@ The methods are called every time one of the following a Spring Data repository * `delete(…)`, `deleteAll(…)`, `deleteAllInBatch(…)`, `deleteInBatch(…)` Note, that these methods take the aggregate root instances as arguments. -This is why `deleteById(…)` is notably absent, as the implementations might choose to issue a query deleting the instance and thus we would never have access to the aggregate instance in the first place. +This is why `deleteById(…)` is notably absent, as the implementations might choose to issue a query deleting the instance, and thus we would never have access to the aggregate instance in the first place. [[core.extensions]] == Spring Data Extensions diff --git a/src/main/java/org/springframework/data/aerospike/annotation/Indexed.java b/src/main/java/org/springframework/data/aerospike/annotation/Indexed.java index 5f05ef730..d423c1bd4 100644 --- a/src/main/java/org/springframework/data/aerospike/annotation/Indexed.java +++ b/src/main/java/org/springframework/data/aerospike/annotation/Indexed.java @@ -16,7 +16,6 @@ package org.springframework.data.aerospike.annotation; -import com.aerospike.client.cdt.CTX; import com.aerospike.client.query.IndexCollectionType; import com.aerospike.client.query.IndexType; @@ -30,13 +29,9 @@ * application's startup. *

* For more details on Secondary index feature please refer to - * Aerospike Secondary index. + * Aerospike Secondary index + * and to indexed-annotation. *

- * Creating a secondary index with context via @Indexed annotation is not supported at the moment - instead use: - * {@link org.springframework.data.aerospike.core.AerospikeOperations#createIndex(Class, String, String, IndexType, - * IndexCollectionType, CTX...)} or for reactive flow: - * {@link org.springframework.data.aerospike.core.ReactiveAerospikeOperations#createIndex(Class, String, String, - * IndexType, IndexCollectionType, CTX...)} * * @author Taras Danylchuk */ diff --git a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java index 8c2232592..56f183e02 100644 --- a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java +++ b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java @@ -23,14 +23,19 @@ public class AerospikeDataSettings { @Builder.Default + // Enable scan operation boolean scansEnabled = false; @Builder.Default + // Send user defined key in addition to hash digest on both reads and writes boolean sendKey = true; @Builder.Default + // Create secondary indexes specified using `@Indexed` annotation on startup boolean createIndexesOnStartup = true; @Builder.Default + // Automatically refresh indexes cache every seconds int indexCacheRefreshFrequencySeconds = 3600; @Builder.Default + // Limit amount of results returned by server. Non-positive value means no limit long queryMaxRecords = 10_000L; // Define how @Id fields (primary keys) and Map keys are stored: false - always as String, // true - preserve original type if supported diff --git a/src/main/java/org/springframework/data/aerospike/core/AerospikeOperations.java b/src/main/java/org/springframework/data/aerospike/core/AerospikeOperations.java index 445dd2234..c35b37f90 100644 --- a/src/main/java/org/springframework/data/aerospike/core/AerospikeOperations.java +++ b/src/main/java/org/springframework/data/aerospike/core/AerospikeOperations.java @@ -50,7 +50,7 @@ public interface AerospikeOperations { /** - * Returns the set name used for the given entityClass in the namespace configured for the AerospikeTemplate in + * Return set name used for the given entityClass in the namespace configured for the AerospikeTemplate in * use. * * @param entityClass The class to get the set name for. @@ -59,7 +59,7 @@ public interface AerospikeOperations { String getSetName(Class entityClass); /** - * Returns the set name used for the given document in the namespace configured for the AerospikeTemplate in use. + * Return set name used for the given document in the namespace configured for the AerospikeTemplate in use. * * @param document The document to get the set name for. * @return The set name used for the given document. @@ -67,7 +67,7 @@ public interface AerospikeOperations { String getSetName(T document); /** - * @return mapping context in use. + * @return Mapping context in use. */ MappingContext getMappingContext(); @@ -77,52 +77,52 @@ public interface AerospikeOperations { MappingAerospikeConverter getAerospikeConverter(); /** - * @return aerospike client in use. + * @return Aerospike client in use. */ IAerospikeClient getAerospikeClient(); /** - * @return value of configuration parameter {@link AerospikeDataSettings#getQueryMaxRecords()}. + * @return Value of configuration parameter {@link AerospikeDataSettings#getQueryMaxRecords()}. */ long getQueryMaxRecords(); /** * Save a document. *

- * If the document has version property - CAS algorithm is used for updating record. Version property is used for - * deciding whether to create a new record or update an existing one. If the version is set to zero - new record - * will be created, creation will fail is such record already exists. If version is greater than zero - existing + * If the document has version property, CAS algorithm is used for updating record. Version property is used for + * deciding whether to create a new record or update an existing one. If the version is set to zero, a new record + * will be created, creation will fail if such record already exists. If the version is greater than zero, existing * record will be updated with {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined * with removing bins at first (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE_ONLY}) - * taking into consideration the version property of the document. Version property will be updated with the - * server's version after successful operation. + * taking into consideration the version property of the document. Document's version property will be updated with + * the server's version after successful operation. *

- * If the document does not have version property - record is updated with + * If the document does not have version property, record is updated with * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE} policy combined with removing bins at first * (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE}). This means that when such record - * does not exist it will be created, otherwise updated - an "upsert". + * does not exist it will be created, otherwise updated (an "upsert"). * - * @param document The document to save. Must not be {@literal null}. + * @param document The document to be saved. Must not be {@literal null}. */ void save(T document); /** - * Save a document with a given set name (overrides the set associated with the document) + * Save a document within the given set (overrides the set associated with the document) *

- * If the document has version property - CAS algorithm is used for updating record. Version property is used for - * deciding whether to create a new record or update an existing one. If the version is set to zero - new record - * will be created, creation will fail is such record already exists. If version is greater than zero - existing + * If the document has version property, CAS algorithm is used for updating record. Version property is used for + * deciding whether to create a new record or update an existing one. If the version is set to zero, a new record + * will be created, creation will fail if such record already exists. If the version is greater than zero, existing * record will be updated with {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined * with removing bins at first (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE_ONLY}) - * taking into consideration the version property of the document. Version property will be updated with the - * server's version after successful operation. + * taking into consideration the version property of the document. Document's version property will be updated with + * the server's version after successful operation. *

- * If the document does not have version property - record is updated with + * If the document does not have version property, record is updated with * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE} policy combined with removing bins at first * (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE}). This means that when such record - * does not exist it will be created, otherwise updated - an "upsert". + * does not exist it will be created, otherwise updated (an "upsert"). * - * @param document The document to save. Must not be {@literal null}. + * @param document The document to be saved. Must not be {@literal null}. * @param setName Set name to override the set associated with the document. */ void save(T document, String setName); @@ -134,7 +134,7 @@ public interface AerospikeOperations { *

* This operation requires Server version 6.0+. * - * @param documents Documents to save. Must not be {@literal null}. + * @param documents The documents to be saved. Must not be {@literal null}. * @throws AerospikeException.BatchRecordArray if batch save succeeds, but results contain errors or null * records * @throws org.springframework.dao.DataAccessException if batch operation failed (see @@ -143,15 +143,15 @@ public interface AerospikeOperations { void saveAll(Iterable documents); /** - * Save multiple documents in one batch request with a given set (overrides the set associated with the documents). + * Save multiple documents within the given set (overrides the default set associated with the documents) in one batch request. * The policies are analogous to {@link #save(Object)}. *

* The order of returned results is preserved. The execution order is NOT preserved. *

* This operation requires Server version 6.0+. * - * @param documents Documents to save. Must not be {@literal null}. - * @param setName Set name to override the set associated with the documents. + * @param documents The documents to be saved. Must not be {@literal null}. + * @param setName Set name to override the default set associated with the documents. * @throws AerospikeException.BatchRecordArray if batch save succeeds, but results contain errors or null * records * @throws org.springframework.dao.DataAccessException if batch operation failed (see @@ -162,19 +162,19 @@ public interface AerospikeOperations { /** * Insert a document using {@link com.aerospike.client.policy.RecordExistsAction#CREATE_ONLY} policy. *

- * If document has version property it will be updated with the server's version after successful operation. + * If the document has version property it will be updated with the server's version after successful operation. * - * @param document The document to insert. Must not be {@literal null}. + * @param document The document to be inserted. Must not be {@literal null}. */ void insert(T document); /** - * Insert a document with a given set name (overrides the set associated with the document) using + * Insert a document within the given set (overrides the set associated with the document) using * {@link com.aerospike.client.policy.RecordExistsAction#CREATE_ONLY} policy. *

- * If document has version property it will be updated with the server's version after successful operation. + * If document has version property, it will be updated with the server's version after successful operation. * - * @param document The document to insert. Must not be {@literal null}. + * @param document The document to be inserted. Must not be {@literal null}. * @param setName Set name to override the set associated with the document. */ void insert(T document, String setName); @@ -186,7 +186,7 @@ public interface AerospikeOperations { *

* This operation requires Server version 6.0+. * - * @param documents Documents to insert. Must not be {@literal null}. + * @param documents Documents to be inserted. Must not be {@literal null}. * @throws AerospikeException.BatchRecordArray if batch insert succeeds, but results contain errors or null * records * @throws org.springframework.dao.DataAccessException if batch operation failed (see @@ -195,14 +195,14 @@ public interface AerospikeOperations { void insertAll(Iterable documents); /** - * Insert multiple documents with a given set name (overrides the set associated with the document) in one batch + * Insert multiple documents within the given set (overrides the set associated with the document) in one batch * request. The policies are analogous to {@link #insert(Object)}. *

* The order of returned results is preserved. The execution order is NOT preserved. *

* This operation requires Server version 6.0+. * - * @param documents Documents to insert. Must not be {@literal null}. + * @param documents Documents to be inserted. Must not be {@literal null}. * @param setName Set name to override the set associated with the document. * @throws AerospikeException.BatchRecordArray if batch insert succeeds, but results contain errors or null * records @@ -214,16 +214,16 @@ public interface AerospikeOperations { /** * Persist a document using specified WritePolicy. * - * @param document The document to persist. Must not be {@literal null}. + * @param document The document to be persisted. Must not be {@literal null}. * @param writePolicy The Aerospike write policy for the inner Aerospike put operation. Must not be * {@literal null}. */ void persist(T document, WritePolicy writePolicy); /** - * Persist a document using specified WritePolicy and a given set (overrides the set associated with the document). + * Persist a document within the given set (overrides the default set associated with the document) using specified WritePolicy. * - * @param document The document to persist. Must not be {@literal null}. + * @param document The document to be persisted. Must not be {@literal null}. * @param writePolicy The Aerospike write policy for the inner Aerospike put operation. Must not be * {@literal null}. * @param setName Set name to override the set associated with the document. @@ -231,64 +231,64 @@ public interface AerospikeOperations { void persist(T document, WritePolicy writePolicy, String setName); /** - * Update a document using {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined with + * Update a record using {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined with * removing bins at first (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE_ONLY}) taking * into consideration the version property of the document if it is present. *

* If document has version property it will be updated with the server's version after successful operation. * - * @param document The document to update. Must not be {@literal null}. + * @param document The document that identifies the record to be updated. Must not be {@literal null}. */ void update(T document); /** - * Update a document with a given set (overrides the set associated with the document) using + * Update a record with the given set (overrides the set associated with the document) using * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined with removing bins at first * (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE_ONLY}) taking into consideration the * version property of the document if it is present. *

* If document has version property it will be updated with the server's version after successful operation. * - * @param document The document to update. Must not be {@literal null}. + * @param document The document that identifies the record to be updated. Must not be {@literal null}. * @param setName Set name to override the set associated with the document. */ void update(T document, String setName); /** - * Update document's specific fields based on a given collection of fields using + * Update specific fields of a record based on the given collection of fields using * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy. You can instantiate the document with * only the relevant fields and specify the list of fields that you want to update. Taking into consideration the * version property of the document if it is present. *

* If document has version property it will be updated with the server's version after successful operation. * - * @param document The document to update. Must not be {@literal null}. + * @param document The document that identifies the record to be updated. Must not be {@literal null}. * @param fields Specific fields to update. */ void update(T document, Collection fields); /** - * Update document's specific fields based on a given collection of fields with a given set (overrides the set - * associated with the document). using {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy. + * Update specific fields of a record based on the given collection of fields with the given set (overrides the set + * associated with the document) using {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy. * You can instantiate the document with only the relevant fields and specify the list of fields that you want to * update. Taking into consideration the version property of the document if it is present. *

* If document has version property it will be updated with the server's version after successful operation. * - * @param document The document to update. Must not be {@literal null}. + * @param document The document that identifies the record to be updated. Must not be {@literal null}. * @param setName Set name to override the set associated with the document. * @param fields Specific fields to update. */ void update(T document, String setName, Collection fields); /** - * Update multiple documents in one batch request. The policies are analogous to {@link #update(Object)}. + * Update multiple records in one batch request. The policies are analogous to {@link #update(Object)}. *

* The order of returned results is preserved. The execution order is NOT preserved. *

* This operation requires Server version 6.0+. * - * @param documents Documents to update. Must not be {@literal null}. + * @param documents The documents that identify the records to be updated. Must not be {@literal null}. * @throws AerospikeException.BatchRecordArray if batch update succeeds, but results contain errors or null * records * @throws org.springframework.dao.DataAccessException if batch operation failed (see @@ -297,14 +297,14 @@ public interface AerospikeOperations { void updateAll(Iterable documents); /** - * Update multiple documents in one batch request with a given set (overrides the set associated with the - * documents). The policies are analogous to {@link #update(Object)}. + * Update multiple records within the given set (overrides the default set associated with the + * documents) in one batch request. The policies are analogous to {@link #update(Object)}. *

* The order of returned results is preserved. The execution order is NOT preserved. *

* This operation requires Server version 6.0+. * - * @param documents Documents to update. Must not be {@literal null}. + * @param documents The documents that identify the records to be updated. Must not be {@literal null}. * @param setName Set name to override the set associated with the document. * @throws AerospikeException.BatchRecordArray if batch update succeeds, but results contain errors or null * records @@ -314,66 +314,66 @@ public interface AerospikeOperations { void updateAll(Iterable documents, String setName); /** - * Truncate/Delete all the documents in the given entity's set. + * Truncate/Delete all records in the set determined by the given entityClass. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @deprecated since 4.6.0, use deleteAll(Class entityClass) instead. */ void delete(Class entityClass); /** - * Delete a document by id, set name will be determined by the given entityClass. + * Delete a record by id, set name will be determined by the given entityClass. * - * @param id The id of the document to delete. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param id The id of the record to delete. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @return whether the document existed on server before deletion. * @deprecated since 4.6.0, use deleteById(Object id, Class entityClass) instead. */ boolean delete(Object id, Class entityClass); /** - * Delete a document. + * Delete a record using the document's id. * - * @param document The document to delete. Must not be {@literal null}. - * @return whether the document existed on server before deletion. + * @param document The document to get set name and id from. Must not be {@literal null}. + * @return Whether the document existed on server before deletion. */ boolean delete(T document); /** - * Delete a document with a given set name. + * Delete a record within the given set using the document's id. * - * @param document The document to delete. Must not be {@literal null}. - * @param setName Set name to delete the document from. - * @return whether the document existed on server before deletion. + * @param document The document to get id from. Must not be {@literal null}. + * @param setName Set name to use. + * @return Whether the document existed on server before deletion. */ boolean delete(T document, String setName); /** - * Delete a document by id, set name will be determined by the given entityClass. + * Delete a record by id, set name will be determined by the given entityClass. * - * @param id The id of the document to delete. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return whether the document existed on server before deletion. + * @param id The id of the record to be deleted. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @return Whether the document existed on server before deletion. */ boolean deleteById(Object id, Class entityClass); /** - * Delete a document by id with a given set name. + * Delete a record by id within the given set. * - * @param id The id of the document to delete. Must not be {@literal null}. - * @param setName Set name to delete the document from. - * @return whether the document existed on server before deletion. + * @param id The id of the record to be deleted. Must not be {@literal null}. + * @param setName Set name to use. + * @return Whether the document existed on server before deletion. */ boolean deleteById(Object id, String setName); /** - * Delete documents by providing multiple ids using a single batch delete operation, set name will be determined by + * Delete records by ids using a single batch delete operation, set name will be determined by * the given entityClass. *

* This operation requires Server version 6.0+. * - * @param ids The ids of the documents to delete. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param ids The ids of the records to be deleted. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be * {@literal null}. * @throws AerospikeException.BatchRecordArray if batch delete results contain errors * @throws org.springframework.dao.DataAccessException if batch operation failed (see @@ -382,12 +382,12 @@ public interface AerospikeOperations { void deleteByIds(Iterable ids, Class entityClass); /** - * Delete documents by providing multiple ids using a single batch delete operation with a given set. + * Delete records by ids within the given set using a single batch delete operation. *

* This operation requires Server version 6.0+. * - * @param ids The ids of the documents to delete. Must not be {@literal null}. - * @param setName Set name to delete the documents from. + * @param ids The ids of the records to be deleted. Must not be {@literal null}. + * @param setName Set name to use. * @throws AerospikeException.BatchRecordArray if batch delete results contain errors * @throws org.springframework.dao.DataAccessException if batch operation failed (see * {@link DefaultAerospikeExceptionTranslator} for details) @@ -395,37 +395,33 @@ public interface AerospikeOperations { void deleteByIds(Iterable ids, String setName); /** - * Batch delete documents by providing their ids. Set name will be determined by the given entityClass. + * Batch delete records by ids. Set name will be determined by the given entityClass. *

* This operation requires Server version 6.0+. * - * @param ids The ids of the documents to delete. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param ids The ids of the records to be deleted. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @throws AerospikeException.BatchRecordArray if batch delete results contain errors or null records */ void deleteByIds(Collection ids, Class entityClass); /** - * Batch delete documents by providing their ids with a given set name. + * Batch delete records by ids within the given set. *

* This operation requires Server version 6.0+. * - * @param ids The ids of the documents to delete. Must not be {@literal null}. - * @param setName Set name to delete the documents from. + * @param ids The ids of the records to be deleted. Must not be {@literal null}. + * @param setName Set name to use. * @throws AerospikeException.BatchRecordArray if batch delete results contain errors or null records */ void deleteByIds(Collection ids, String setName); /** - * Executes a single batch delete for several entities. - *

- * Aerospike provides functionality to delete documents from different sets in 1 batch request. The methods allow to - * put grouped keys by entity type as parameter and get result as spring data aerospike entities grouped by entity - * type. + * Perform a single batch delete for records from different sets. *

* This operation requires Server version 6.0+. * - * @param groupedKeys Must not be {@literal null}. + * @param groupedKeys Keys grouped by document type. Must not be {@literal null}. * @throws AerospikeException.BatchRecordArray if batch delete results contain errors * @throws org.springframework.dao.DataAccessException if batch operation failed (see * {@link DefaultAerospikeExceptionTranslator} for details) @@ -433,563 +429,542 @@ public interface AerospikeOperations { void deleteByIds(GroupedKeys groupedKeys); /** - * Truncate/Delete all the documents in the given entity's set. + * Truncate/Delete all records in the set determined by the given entity class. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. */ void deleteAll(Class entityClass); /** - * Truncate/Delete all the documents in the given set. + * Truncate/Delete all documents in the given set. * - * @param setName Set name to truncate/delete all the documents in. + * @param setName Set name to truncate/delete all records in. */ void deleteAll(String setName); /** - * Add integer/double bin values to existing document bin values, read the new modified document and map it back the - * given document class type. + * Find an existing record matching the document's class and id, add map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the record to. Must not be * {@literal null}. - * @param values a Map of bin names and values to add. Must not be {@literal null}. - * @return Modified document after add operations. + * @param values The Map of bin names and values to add. Must not be {@literal null}. + * @return Modified record mapped to the document's class. */ T add(T document, Map values); /** - * Add integer/double bin values to existing document bin values with a given set name, read the new modified - * document and map it back to the given document class type. + * Find an existing record matching the document's id and the given set name, add map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get id from and to map the record to. Must not be * {@literal null}. - * @param setName Set name for the operation. - * @param values a Map of bin names and values to add. Must not be {@literal null}. - * @return Modified document after add operations. + * @param setName Set name to use. + * @param values The Map of bin names and values to add. Must not be {@literal null}. + * @return Modified record mapped to the document's class. */ T add(T document, String setName, Map values); /** - * Add integer/double bin value to existing document bin value, read the new modified document and map it back the - * given document class type. + * Find an existing record matching the document's class and id, add specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the record to. Must not be * {@literal null}. * @param binName Bin name to use add operation on. Must not be {@literal null}. * @param value The value to add. - * @return Modified document after add operation. + * @return Modified record mapped to the document's class. */ T add(T document, String binName, long value); /** - * Add integer/double bin value to existing document bin value with a given set name, read the new modified document - * and map it back to the given document class type. + * Find an existing record matching the document's id and the given set name, add specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get id from and to map the record to. Must not be * {@literal null}. - * @param setName Set name for the operation. + * @param setName Set name to use. * @param binName Bin name to use add operation on. Must not be {@literal null}. * @param value The value to add. - * @return Modified document after add operation. + * @return Modified record mapped to the document's class. */ T add(T document, String setName, String binName, long value); /** - * Append bin string values to existing document bin values, read the new modified document and map it back the - * given document class type. + * Find an existing record matching the document's class and id, append map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the record to. Must not be * {@literal null}. - * @param values a Map of bin names and values to append. Must not be {@literal null}. - * @return Modified document after append operations. + * @param values The Map of bin names and values to append. Must not be {@literal null}. + * @return Modified record mapped to the document's class. */ T append(T document, Map values); /** - * Append bin string values to existing document bin values with a given set name, read the new modified document - * and map it back to the given document class type. + * Find an existing record matching the document's id and the given set name, append map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to map the document to. Must not be {@literal null}. - * @param setName Set name for the operation. - * @param values a Map of bin names and values to append. Must not be {@literal null}. - * @return Modified document after append operations. + * @param document The document to get id from and to map the record to. Must not be {@literal null}. + * @param setName Set name to use. + * @param values The Map of bin names and values to append. Must not be {@literal null}. + * @return Modified record mapped to the document's class. */ T append(T document, String setName, Map values); /** - * Append bin string value to existing document bin value, read the new modified document and map it back the given - * document class type. + * Find an existing record matching the document's class and id, append specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the record to. Must not be * {@literal null}. * @param binName Bin name to use append operation on. * @param value The value to append. - * @return Modified document after append operation. + * @return Modified record mapped to the document's class. */ T append(T document, String binName, String value); /** - * Append bin string value to existing document bin value with a given set name, read the new modified document and - * map it back to the given document class type. + * Find an existing record matching the document's id and the given set name, append specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to map the document to. Must not be {@literal null}. - * @param setName Set name for the operation. + * @param document The document to get id from and to map the record to. Must not be {@literal null}. + * @param setName Set name to use. * @param binName Bin name to use append operation on. * @param value The value to append. - * @return Modified document after append operation. + * @return Modified record mapped to the document's class. */ T append(T document, String setName, String binName, String value); /** - * Prepend bin string values to existing document bin values, read the new modified document and map it back the - * given document class type. + * Find an existing record matching the document's class and id, prepend map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the record to. Must not be * {@literal null}. - * @param values a Map of bin names and values to prepend. Must not be {@literal null}. - * @return Modified document after prepend operations. + * @param values The Map of bin names and values to prepend. Must not be {@literal null}. + * @return Modified record mapped to the document's class. */ T prepend(T document, Map values); /** - * Prepend bin string values to existing document bin values with a given set name, read the new modified document - * and map it back to the given document class type. + * Find an existing record matching the document's id and the given set name, prepend map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to map the document to. Must not be {@literal null}. - * @param setName Set name for the operation. - * @param values a Map of bin names and values to prepend. Must not be {@literal null}. - * @return Modified document after prepend operations. + * @param document The document to get id from and to map the record to. Must not be {@literal null}. + * @param setName Set name to use. + * @param values The Map of bin names and values to prepend. Must not be {@literal null}. + * @return Modified record mapped to the document's class. */ T prepend(T document, String setName, Map values); /** - * Prepend bin string value to existing document bin value, read the new modified document and map it back the given - * document class type. + * Find an existing record matching the document's class and id, prepend specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the record to. Must not be * {@literal null}. * @param binName Bin name to use prepend operation on. * @param value The value to prepend. - * @return Modified document after prepend operation. + * @return Modified record mapped to the document's class. */ T prepend(T document, String binName, String value); /** - * Prepend bin string value to existing document bin value with a given set name, read the new modified document and - * map it back to the given document class type. + * Find an existing record matching the document's id and the given set name, prepend specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to map the document to. Must not be {@literal null}. - * @param setName Set name for the operation. + * @param document The document to get id from and to map the record to. Must not be {@literal null}. + * @param setName Set name to use. * @param binName Bin name to use prepend operation on. * @param value The value to prepend. - * @return Modified document after prepend operation. + * @return Modified record mapped to the document's class. */ T prepend(T document, String setName, String binName, String value); /** - * Execute operation against underlying store. + * Execute an operation against underlying store. * * @param supplier must not be {@literal null}. - * @return Execution result. + * @return The resulting document. */ T execute(Supplier supplier); /** - * Find a document by id, set name will be determined by the given entityClass. + * Find a record by id, set name will be determined by the given entityClass. *

- * Document will be mapped to the given entityClass. + * The resulting The record will be mapped to the given entityClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the document to. Must not be + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to extract set name from and to map the record to. Must not be * {@literal null}. - * @return The document from Aerospike, returned document will be mapped to entityClass's type, if document doesn't - * exist return null. + * @return The document mapped to entityClass's type or null if nothing is found */ T findById(Object id, Class entityClass); /** - * Find a document by id with a given set name. + * Find a record by id within the given set. *

- * Document will be mapped to the given entityClass. + * The record will be mapped to the given entityClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to map the document to and to get entity properties from (such expiration). Must not + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to map the record to and to get entity properties from (such as expiration). Must not * be {@literal null}. * @param setName Set name to find the document from. - * @return The document from Aerospike, returned document will be mapped to entityClass's type, if document doesn't - * exist return null. + * @return The record mapped to entityClass's type or null if document does not exist */ T findById(Object id, Class entityClass, String setName); /** - * Find a document by id, set name will be determined by the given entityClass. + * Find a record by id, set name will be determined by the given entityClass. *

- * Document will be mapped to the given entityClass. + * The record will be mapped to the given entityClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return The document from Aerospike, returned document will be mapped to targetClass's type, if document doesn't - * exist return null. + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return The record mapped to targetClass's type or null if document doesn't + * exist. */ S findById(Object id, Class entityClass, Class targetClass); /** - * Find a document by id with a given set name. + * Find a record by id within the given set. *

- * Document will be mapped to the given entityClass. + * The record will be mapped to the given entityClass. * - * @param id The id of the document to find. Must not be {@literal null}. + * @param id The id of the record to find. Must not be {@literal null}. * @param entityClass The class to get entity properties from (such as expiration). Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. * @param setName Set name to find the document from. - * @return The document from Aerospike, returned document will be mapped to targetClass's type, if document doesn't - * exist return null. + * @return The record mapped to targetClass's type or null if document doesn't + * exist. */ S findById(Object id, Class entityClass, Class targetClass, String setName); /** - * Find documents by providing multiple ids using a single batch read operation, set name will be determined by the + * Find records by ids using a single batch read operation, set name will be determined by the * given entityClass. *

- * Documents will be mapped to the given entityClass. + * The records will be mapped to the given entityClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract set name from and to map the records to. Must not be * {@literal null}. - * @return The documents from Aerospike, returned documents will be mapped to entityClass's type, if no document + * @return The matching records mapped to entityClass's type, if no document * exists, an empty list is returned. */ List findByIds(Iterable ids, Class entityClass); /** - * Find documents with a given set name by providing multiple ids using a single batch read operation. + * Find records by ids within the given set using a single batch read operation. *

- * Documents will be mapped to the given entityClass. + * The records will be mapped to the given entityClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to map the documents to. Must not be {@literal null}. - * @param setName Set name to find the document from. - * @return The documents from Aerospike, returned documents will be mapped to entityClass's type, if no document - * exists, an empty list is returned. + * @param entityClass The class to map the records to. Must not be {@literal null}. + * @param setName Set name to use. + * @return The matching records mapped to entityClass's type or an empty list if nothing found. */ List findByIds(Iterable ids, Class entityClass, String setName); /** - * Find documents by providing multiple ids using a single batch read operation, set name will be determined by the + * Find records by ids using a single batch read operation, set name will be determined by the * given entityClass. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return The documents from Aerospike, returned documents will be mapped to targetClass's type, if no document - * exists, an empty list is returned. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return The matching records mapped to targetClass's type or an empty list if nothing found. */ List findByIds(Iterable ids, Class entityClass, Class targetClass); /** - * Find documents with a given set name by providing multiple ids using a single batch read operation. + * Find records by ids within the given set using a single batch read operation. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. * @param entityClass The class to get entity properties from (such as expiration). Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @param setName Set name to find the document from. - * @return The documents from Aerospike, returned documents will be mapped to targetClass's type, if no document - * exists, an empty list is returned. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @param setName Set name to use. + * @return The matching records mapped to targetClass's type or an empty list if nothing found. */ List findByIds(Iterable ids, Class entityClass, Class targetClass, String setName); /** - * Executes a single batch request to get results for several entities. + * Execute a single batch request to find several records, possibly from different sets. *

- * Aerospike provides functionality to get documents from different sets in 1 batch request. The methods allow to - * put grouped keys by entity type as parameter and get result as spring data aerospike entities grouped by entity - * type. + * Aerospike provides functionality to get records from different sets in 1 batch request. This method receives + * keys grouped by document type as a parameter and returns Aerospike records mapped to documents grouped by type. * * @param groupedKeys Must not be {@literal null}. - * @return grouped entities. + * @return grouped documents. */ GroupedEntities findByIds(GroupedKeys groupedKeys); /** - * Find document by providing id, set name will be determined by the given entityClass. + * Find a record by id using a query, set name will be determined by the given entityClass. *

- * Documents will be mapped to the given targetClass. + * The record will be mapped to the given targetClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. * @param query The {@link Query} to filter results. Optional argument (null if no filtering required). - * @return The document from Aerospike, returned document will be mapped to targetClass's type. + * @return The matching record mapped to targetClass's type. */ Object findByIdUsingQuery(Object id, Class entityClass, Class targetClass, @Nullable Query query); /** - * Find document by providing id with a given set name. + * Find a record by id within the given set using a query. *

- * Documents will be mapped to the given targetClass. + * The record will be mapped to the given targetClass. * - * @param id The id of the document to find. Must not be {@literal null}. + * @param id The id of the record to find. Must not be {@literal null}. * @param entityClass The class to get the entity properties from (such as expiration). Must not be * {@literal null}. - * @param targetClass The class to map the document to. - * @param setName Set name to find the document from. + * @param targetClass The class to map the record to. + * @param setName Set name to use. * @param query The {@link Query} to filter results. Optional argument (null if no filtering required). - * @return The document from Aerospike, returned document will be mapped to targetClass's type. + * @return The matching record mapped to targetClass's type. */ Object findByIdUsingQuery(Object id, Class entityClass, Class targetClass, String setName, @Nullable Query query); /** - * Find documents by providing multiple ids, set name will be determined by the given entityClass. + * Find records by ids and a query, set name will be determined by the given entityClass. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. * @param query The {@link Query} to filter results. Optional argument (null if no filtering required). - * @return The documents from Aerospike, returned documents will be mapped to targetClass's type if provided - * (otherwise to entityClass's type), if no document exists, an empty list is returned. + * @return The matching records mapped to targetClass's type if provided + * (otherwise to entityClass's type), or an empty list if no documents found. */ List findByIdsUsingQuery(Collection ids, Class entityClass, Class targetClass, @Nullable Query query); /** - * Find documents by providing multiple ids with a given set name. + * Find records by ids within the given set. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. * @param entityClass The class to get the entity properties from (such as expiration). Must not be * {@literal null}. - * @param targetClass The class to map the document to. - * @param setName Set name to find the document from. + * @param targetClass The class to map the record to. + * @param setName Set name to use. * @param query The {@link Query} to filter results. Optional argument (null if no filtering required). - * @return The documents from Aerospike, returned documents will be mapped to targetClass's type if provided - * (otherwise to entityClass's type), if no document exists, an empty list is returned. + * @return The matching records mapped to targetClass's type if provided + * (otherwise to entityClass's type), or an empty list if no documents found. */ List findByIdsUsingQuery(Collection ids, Class entityClass, Class targetClass, String setName, @Nullable Query query); /** - * Find documents in the given entityClass's set using a query and map them to the given class type. + * Find records in the given entityClass's set using a query and map them to the given class type. * * @param query The {@link Query} to filter results. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract set name from and to map the records to. Must not be * {@literal null}. - * @return A Stream of matching documents, returned documents will be mapped to entityClass's type. + * @return A Stream of matching records mapped to entityClass type. */ Stream find(Query query, Class entityClass); /** - * Find documents in the given entityClass's set using a query and map them to the given target class type. + * Find records in the given entityClass's set using a query and map them to the given target class type. * * @param query The {@link Query} to filter results. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A Stream of matching documents, returned documents will be mapped to targetClass's type. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Stream of matching records mapped to targetClass type. */ Stream find(Query query, Class entityClass, Class targetClass); /** - * Find documents in the given set using a query and map them to the given target class type. + * Find records in the given set using a query and map them to the given target class type. * * @param query The {@link Query} to filter results. Must not be {@literal null}. - * @param setName Set name to find the documents in. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A Stream of matching documents, returned documents will be mapped to targetClass's type. + * @param setName Set name to use. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Stream of matching records mapped to targetClass type. */ Stream find(Query query, Class targetClass, String setName); /** - * Find all documents in the given entityClass's set and map them to the given class type. + * Find all records in the given entityClass's set and map them to the given class type. * - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract set name from and to map the records to. Must not be * {@literal null}. - * @return A Stream of matching documents, returned documents will be mapped to entityClass's type. + * @return A Stream of matching records mapped to entityClass type. */ Stream findAll(Class entityClass); /** - * Find all documents in the given entityClass's set and map them to the given target class type. + * Find all records in the given entityClass's set and map them to the given target class type. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A Stream of matching documents, returned documents will be mapped to targetClass's type. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Stream of matching records mapped to targetClass type. */ Stream findAll(Class entityClass, Class targetClass); /** - * Find all documents in the given set and map them to the given class type. + * Find all records in the given set and map them to the given class type. * - * @param targetClass The class to map the documents to. Must not be {@literal null}. - * @param setName Set name to find all documents. - * @return A Stream of matching documents, returned documents will be mapped to entityClass's type. + * @param targetClass The class to map the records to. Must not be {@literal null}. + * @param setName Set name to use. + * @return A Stream of matching records mapped to entityClass type. */ Stream findAll(Class targetClass, String setName); /** - * Find all documents in the given entityClass's set using a provided sort and map them to the given class type. + * Find all records in the given entityClass's set using a provided sort and map them to the given class type. * * @param sort The sort to affect the returned iterable documents order. * @param offset The offset to start the range from. * @param limit The limit of the range. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. - * @return A stream of matching documents, returned documents will be mapped to entityClass's type. + * @param entityClass The class to extract set name from and to map the records to. + * @return A Stream of matching records mapped to entityClass type. */ Stream findAll(Sort sort, long offset, long limit, Class entityClass); /** - * Find all documents in the given entityClass's set using a provided sort and map them to the given target class + * Find all records in the given entityClass's set using a provided sort and map them to the given target class * type. * * @param sort The sort to affect the returned iterable documents order. * @param offset The offset to start the range from. * @param limit The limit of the range. - * @param entityClass The class to extract the Aerospike set from. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A stream of matching documents, returned documents will be mapped to targetClass's type. + * @param entityClass The class to extract set name from. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Stream of matching records mapped to targetClass type. */ Stream findAll(Sort sort, long offset, long limit, Class entityClass, Class targetClass); /** - * Find all documents in the given set using a provided sort and map them to the given target class type. + * Find all records in the given set using a provided sort and map them to the given target class type. * * @param sort The sort to affect the returned iterable documents order. * @param offset The offset to start the range from. * @param limit The limit of the range. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @param setName Set name to find the documents. - * @return A stream of matching documents, returned documents will be mapped to targetClass's type. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @param setName Set name to use. + * @return A Stream of matching records mapped to targetClass type. */ Stream findAll(Sort sort, long offset, long limit, Class targetClass, String setName); /** - * Find documents in the given entityClass's set using a range (offset, limit) and a sort and map them to the given + * Find records in the given entityClass's set using a range (offset, limit) and a sort and map them to the given * class type. * * @param offset The offset to start the range from. * @param limit The limit of the range. * @param sort The sort to affect the order of the returned Stream of documents. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract set name from and to map the records to. Must not be * {@literal null}. - * @return A Stream of matching documents, returned documents will be mapped to entityClass's type. + * @return A Stream of matching records mapped to entityClass type. */ Stream findInRange(long offset, long limit, Sort sort, Class entityClass); /** - * Find documents in the given entityClass's set using a range (offset, limit) and a sort and map them to the given + * Find records in the given entityClass's set using a range (offset, limit) and a sort and map them to the given * target class type. * * @param offset The offset to start the range from. * @param limit The limit of the range. * @param sort The sort to affect the returned Stream of documents order. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A Stream of matching documents, returned documents will be mapped to targetClass's type. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Stream of matching records mapped to targetClass type. */ Stream findInRange(long offset, long limit, Sort sort, Class entityClass, Class targetClass); /** - * Find documents in the given set using a range (offset, limit) and a sort and map them to the given target class + * Find records in the given set using a range (offset, limit) and a sort and map them to the given target class * type. * * @param offset The offset to start the range from. * @param limit The limit of the range. * @param sort The sort to affect the returned Stream of documents order. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @param setName Set name to find the documents. - * @return A Stream of matching documents, returned documents will be mapped to targetClass's type. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @param setName Set name to use. + * @return A Stream of matching records mapped to targetClass type. */ Stream findInRange(long offset, long limit, Sort sort, Class targetClass, String setName); /** - * Find documents in the given entityClass's set using a query and map them to the given target class type. If the + * Find records in the given entityClass set using a query and map them to the given target class type. If the * query has pagination and/or sorting, post-processing must be applied separately. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the records to. * @param query The {@link Query} to filter results. - * @return A Stream of all matching documents regardless of pagination/sorting, returned documents will be mapped to - * targetClass's type. + * @return A Stream of all matching records (regardless of pagination/sorting) mapped to targetClass type. */ Stream findUsingQueryWithoutPostProcessing(Class entityClass, Class targetClass, Query query); /** - * Check if a document exists by providing document id and entityClass (set name will be determined by the given - * entityClass). + * Check by id if a record exists within the set associated with the given entityClass. * - * @param id The id to check if exists. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return whether the document exists. + * @param id The id to check for record existence. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @return whether the matching record exists. */ boolean exists(Object id, Class entityClass); /** - * Check if a document exists by providing document id and a set name. + * Check by id if a record exists within the given set name. * - * @param id The id to check if exists. Must not be {@literal null}. - * @param setName Set name to check if document exists. - * @return whether the document exists. + * @param id The id to check for record existence. Must not be {@literal null}. + * @param setName Set name to use. + * @return whether the matching record exists. */ boolean exists(Object id, String setName); /** - * Check if any document exists by defining a query and entityClass (set name will be determined by the given - * entityClass). + * Check using a query if any matching records exist within the set associated with the given entityClass. * - * @param query The query to check if any returned document exists. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return whether any document exists. + * @param query The query to check if any matching records exist. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @return whether any matching records exist. */ boolean existsByQuery(Query query, Class entityClass); /** - * Check if any document exists by defining a query, entityClass and a given set name. + * Check using a query if any matching records exist within the given set. * - * @param query The query to check if any returned document exists. Must not be {@literal null}. - * @param entityClass The class to translate to returned results into. Must not be {@literal null}. - * @param setName The set name to check if documents exists in. Must not be {@literal null}. - * @return whether any document exists. + * @param query The query to check if any matching records exist. Must not be {@literal null}. + * @param entityClass The class to translate to returned records into. Must not be {@literal null}. + * @param setName Set name to use. Must not be {@literal null}. + * @return whether any matching records exist. */ boolean existsByQuery(Query query, Class entityClass, String setName); /** - * Return the amount of documents in the given entityClass's Aerospike set. + * Return the amount of records in the set determined by the given entityClass. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return amount of documents in the set (of the given entityClass). + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @return amount of records in the set of the given entityClass. */ long count(Class entityClass); /** - * Return the amount of documents in the given Aerospike set. + * Return the amount of records in the given Aerospike set. * * @param setName The name of the set to count. Must not be {@literal null}. - * @return amount of documents in the given set. + * @return amount of records in the given set. */ long count(String setName); /** - * Return the amount of documents in query results. Set name will be determined by the given entityClass. + * Return the amount of records in query results. Set name will be determined by the given entityClass. * * @param query The query that provides the result set for count. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return amount of documents that the given query and entity class supplied. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @return amount of records matching the given query and entity class. */ long count(Query query, Class entityClass); /** - * Return the amount of documents in query results with a given set name. + * Return the amount of records in query results within the given set. * * @param query The query that provides the result set for count. - * @param setName Set name to count the documents from. - * @return amount of documents that the given query and entity class supplied. + * @param setName Set name to use. + * @return amount of documents matching the given query and set. */ long count(Query query, String setName); @@ -997,7 +972,7 @@ List findByIdsUsingQuery(Collection ids, Class entityClass, Clas * Execute query, apply statement's aggregation function, and return result iterator. * * @param filter The filter to pass to the query. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param module server package where user defined function resides. * @param function aggregation function name. * @param arguments arguments to pass to function name, if any. @@ -1006,10 +981,10 @@ List findByIdsUsingQuery(Collection ids, Class entityClass, Clas ResultSet aggregate(Filter filter, Class entityClass, String module, String function, List arguments); /** - * Execute query with a given set name, apply statement's aggregation function, and return result iterator. + * Execute query within the given set, apply statement's aggregation function, and return result iterator. * * @param filter The filter to pass to the query. - * @param setName Set name to aggregate the documents from. + * @param setName Set name to use. * @param module server package where user defined function resides. * @param function aggregation function name. * @param arguments arguments to pass to function name, if any. @@ -1020,7 +995,7 @@ List findByIdsUsingQuery(Collection ids, Class entityClass, Clas /** * Create an index with the specified name in Aerospike. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1031,7 +1006,7 @@ void createIndex(Class entityClass, String indexName, String binName, /** * Create an index with the specified name in Aerospike. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1043,7 +1018,7 @@ void createIndex(Class entityClass, String indexName, String binName, /** * Create an index with the specified name in Aerospike. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1056,7 +1031,7 @@ void createIndex(Class entityClass, String indexName, String binName, /** * Create an index with the specified name in Aerospike. * - * @param setName Set name to create the index. + * @param setName Set name to use. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1067,7 +1042,7 @@ void createIndex(String setName, String indexName, String binName, /** * Create an index with the specified name in Aerospike. * - * @param setName Set name to create the index. + * @param setName Set name to use. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1079,7 +1054,7 @@ void createIndex(String setName, String indexName, String binName, /** * Create an index with the specified name in Aerospike. * - * @param setName Set name to create the index. + * @param setName Set name to use. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1090,23 +1065,23 @@ void createIndex(String setName, String indexName, String binName, IndexType indexType, IndexCollectionType indexCollectionType, CTX... ctx); /** - * Delete an index with the specified name from Aerospike. + * Delete an index with the specified name in Aerospike. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param indexName The index name. Must not be {@literal null}. */ void deleteIndex(Class entityClass, String indexName); /** - * Delete an index with the specified name from Aerospike with a given set name. + * Delete an index with the specified name within the given set in Aerospike. * - * @param setName Set name to delete the index from. + * @param setName Set name to use. * @param indexName The index name. Must not be {@literal null}. */ void deleteIndex(String setName, String indexName); /** - * Checks whether an index with the specified name exists in Aerospike. + * Check whether an index with the specified name exists in Aerospike. * * @param indexName The Aerospike index name. Must not be {@literal null}. * @return true if exists diff --git a/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java b/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java index 8eb4f95a9..d46a6572f 100644 --- a/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java +++ b/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java @@ -164,6 +164,7 @@ public void saveAll(Iterable documents, String setName) { List batchWriteRecords = batchWriteDataList.stream().map(BatchWriteData::batchRecord).toList(); try { + // requires server ver. >= 6.0.0 client.operate(null, batchWriteRecords); } catch (AerospikeException e) { throw translateError(e); @@ -234,6 +235,7 @@ public void insertAll(Iterable documents, String setName) { List batchWriteRecords = batchWriteDataList.stream().map(BatchWriteData::batchRecord).toList(); try { + // requires server ver. >= 6.0.0 client.operate(null, batchWriteRecords); } catch (AerospikeException e) { throw translateError(e); @@ -330,6 +332,7 @@ public void updateAll(Iterable documents, String setName) { List batchWriteRecords = batchWriteDataList.stream().map(BatchWriteData::batchRecord).toList(); try { + // requires server ver. >= 6.0.0 client.operate(null, batchWriteRecords); } catch (AerospikeException e) { throw translateError(e); @@ -435,6 +438,7 @@ public void deleteByIds(Collection ids, String setName) { .map(id -> getKey(id, setName)) .toArray(Key[]::new); + // requires server ver. >= 6.0.0 deleteAndHandleErrors(client, keys); } diff --git a/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeOperations.java b/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeOperations.java index 6d5a19640..f39b4bcde 100644 --- a/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeOperations.java +++ b/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeOperations.java @@ -44,7 +44,7 @@ public interface ReactiveAerospikeOperations { /** - * @return mapping context in use. + * @return Mapping context in use. */ MappingContext getMappingContext(); @@ -54,53 +54,53 @@ public interface ReactiveAerospikeOperations { MappingAerospikeConverter getAerospikeConverter(); /** - * @return aerospike reactive client in use. + * @return Aerospike reactive client in use. */ IAerospikeReactorClient getAerospikeReactorClient(); /** - * @return value of configuration parameter {@link AerospikeDataSettings#getQueryMaxRecords()}. + * @return Value of configuration parameter {@link AerospikeDataSettings#getQueryMaxRecords()}. */ long getQueryMaxRecords(); /** - * Reactively save document. + * Reactively save a document. *

- * If document has version property - CAS algorithm is used for updating record. Version property is used for - * deciding whether to create new record or update existing. If version is set to zero - new record will be created, - * creation will fail is such record already exists. If version is greater than zero - existing record will be - * updated with {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined with removing + * If the document has version property, CAS algorithm is used for updating record. Version property is used for + * deciding whether to create new record or update existing. If the version is set to zero, a new record will be + * created, creation will fail if such record already exists. If version is greater than zero, existing record will + * be updated with {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined with removing * bins at first (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE_ONLY}) taking into * consideration the version property of the document. Version property will be updated with the server's version * after successful operation. *

- * If document does not have version property - record is updated with + * If the document does not have version property, the record is updated with * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE} policy combined with removing bins at first * (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE}). This means that when such record - * does not exist it will be created, otherwise updated - an "upsert". + * does not exist it will be created, otherwise updated (an "upsert"). * - * @param document The document to save. Must not be {@literal null}. + * @param document The document to be saved. Must not be {@literal null}. * @return A Mono of the new saved document. */ Mono save(T document); /** - * Reactively save document with a given set name. + * Reactively save a document within the given set. *

- * If document has version property - CAS algorithm is used for updating record. Version property is used for - * deciding whether to create new record or update existing. If version is set to zero - new record will be created, - * creation will fail is such record already exists. If version is greater than zero - existing record will be - * updated with {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined with removing + * If the document has version property, CAS algorithm is used for updating record. Version property is used for + * deciding whether to create new record or update existing. If the version is set to zero, a new record will be + * created, creation will fail if such record already exists. If version is greater than zero, existing record will + * be updated with {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined with removing * bins at first (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE_ONLY}) taking into * consideration the version property of the document. Version property will be updated with the server's version * after successful operation. *

- * If document does not have version property - record is updated with + * If the document does not have version property, the record is updated with * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE} policy combined with removing bins at first * (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE}). This means that when such record - * does not exist it will be created, otherwise updated - an "upsert". + * does not exist it will be created, otherwise updated (an "upsert"). * - * @param document The document to save. Must not be {@literal null}. + * @param document The document to be saved. Must not be {@literal null}. * @param setName The set name to save the document. * @return A Mono of the new saved document. */ @@ -113,7 +113,7 @@ public interface ReactiveAerospikeOperations { *

* Requires Server version 6.0+. * - * @param documents documents to save. Must not be {@literal null}. + * @param documents The documents to be saved. Must not be {@literal null}. * @return A Flux of the saved documents, otherwise onError is signalled with * {@link AerospikeException.BatchRecordArray} if batch save results contain errors, or with * {@link org.springframework.dao.DataAccessException} if batch operation failed. @@ -121,14 +121,14 @@ public interface ReactiveAerospikeOperations { Flux saveAll(Iterable documents); /** - * Reactively save documents using one batch request with a given set name. The policies are analogous to + * Reactively save documents within the given set using one batch request. The policies are analogous to * {@link #save(Object)}. *

* The order of returned results is preserved. The execution order is NOT preserved. *

* Requires Server version 6.0+. * - * @param documents documents to save. Must not be {@literal null}. + * @param documents The documents to be saved. Must not be {@literal null}. * @param setName The set name to save to documents. * @return A Flux of the saved documents, otherwise onError is signalled with * {@link AerospikeException.BatchRecordArray} if batch save results contain errors, or with @@ -137,22 +137,22 @@ public interface ReactiveAerospikeOperations { Flux saveAll(Iterable documents, String setName); /** - * Reactively insert document using {@link com.aerospike.client.policy.RecordExistsAction#CREATE_ONLY} policy. + * Reactively insert a document using {@link com.aerospike.client.policy.RecordExistsAction#CREATE_ONLY} policy. *

- * If document has version property it will be updated with the server's version after successful operation. + * If the document has version property it will be updated with the server's version after successful operation. * - * @param document The document to insert. Must not be {@literal null}. + * @param document The document to be inserted. Must not be {@literal null}. * @return A Mono of the new inserted document. */ Mono insert(T document); /** - * Reactively insert document with a given set name using + * Reactively insert a document within the given set using * {@link com.aerospike.client.policy.RecordExistsAction#CREATE_ONLY} policy. *

- * If document has version property it will be updated with the server's version after successful operation. + * If the document has version property it will be updated with the server's version after successful operation. * - * @param document The document to insert. Must not be {@literal null}. + * @param document The document to be inserted. Must not be {@literal null}. * @param setName The set name to insert the document. * @return A Mono of the new inserted document. */ @@ -173,7 +173,7 @@ public interface ReactiveAerospikeOperations { Flux insertAll(Iterable documents); /** - * Reactively insert documents with a given set using one batch request. The policies are analogous to + * Reactively insert documents within the given set using one batch request. The policies are analogous to * {@link #insert(Object)}. *

* The order of returned results is preserved. The execution order is NOT preserved. @@ -191,7 +191,7 @@ public interface ReactiveAerospikeOperations { /** * Reactively persist a document using specified WritePolicy. * - * @param document The document to persist. Must not be {@literal null}. + * @param document The document to be persisted. Must not be {@literal null}. * @param writePolicy The Aerospike write policy for the inner Aerospike put operation. Must not be * {@literal null}. * @return A Mono of the new persisted document. @@ -199,10 +199,10 @@ public interface ReactiveAerospikeOperations { Mono persist(T document, WritePolicy writePolicy); /** - * Reactively persist a document using specified WritePolicy and a given set (overrides the set associated with the - * document). + * Reactively persist a document within the given set (overrides the default set associated with the document) + * using specified WritePolicy. * - * @param document The document to persist. Must not be {@literal null}. + * @param document The document to be persisted. Must not be {@literal null}. * @param writePolicy The Aerospike write policy for the inner Aerospike put operation. Must not be * {@literal null}. * @param setName Set name to override the set associated with the document. @@ -211,67 +211,67 @@ public interface ReactiveAerospikeOperations { Mono persist(T document, WritePolicy writePolicy, String setName); /** - * Reactively update document using {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy + * Reactively update a record using {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy * combined with removing bins at first (analogous to * {@link com.aerospike.client.policy.RecordExistsAction#REPLACE_ONLY}) taking into consideration the version * property of the document if it is present. *

- * If document has version property it will be updated with the server's version after successful operation. + * If the document has version property it will be updated with the server's version after successful operation. * - * @param document The document to update. Must not be {@literal null}. + * @param document The document that identifies the record to be updated. Must not be {@literal null}. * @return A Mono of the new updated document. */ Mono update(T document); /** - * Reactively update document with a given set using + * Reactively update a record within the given set using * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy combined with removing bins at first * (analogous to {@link com.aerospike.client.policy.RecordExistsAction#REPLACE_ONLY}) taking into consideration the * version property of the document if it is present. *

* If document has version property it will be updated with the server's version after successful operation. * - * @param document The document to update. Must not be {@literal null}. + * @param document The document that identifies the record to be updated. Must not be {@literal null}. * @param setName The set name to update the document. * @return A Mono of the new updated document. */ Mono update(T document, String setName); /** - * Reactively update document specific fields based on a given collection of fields. using - * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy - You can instantiate the document with - * only relevant fields and specify the list of fields that you want to update. taking into consideration the + * Reactively update specific bins of a record based on the given collection of fields using + * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy. You can instantiate the document with + * only relevant fields and specify the list of fields that you want to update, taking into consideration the * version property of the document if it is present. *

* If document has version property it will be updated with the server's version after successful operation. * - * @param document The document to update. Must not be {@literal null}. + * @param document The document that identifies the record to be updated. Must not be {@literal null}. * @return A Mono of the new updated document. */ Mono update(T document, Collection fields); /** - * Reactively update document specific fields based on a given collection of fields with a given set name. using - * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy - You can instantiate the document with - * only relevant fields and specify the list of fields that you want to update. taking into consideration the + * Reactively update specific fields of a record based on the given collection of fields within the given set using + * {@link com.aerospike.client.policy.RecordExistsAction#UPDATE_ONLY} policy. You can instantiate the document with + * only relevant fields and specify the list of fields that you want to update, taking into consideration the * version property of the document if it is present. *

* If document has version property it will be updated with the server's version after successful operation. * - * @param document The document to update. Must not be {@literal null}. + * @param document The document that identifies the record to be updated. Must not be {@literal null}. * @param setName The set name to update the document. * @return A Mono of the new updated document. */ Mono update(T document, String setName, Collection fields); /** - * Reactively update documents using one batch request. The policies are analogous to {@link #update(Object)}. + * Reactively update records using one batch request. The policies are analogous to {@link #update(Object)}. *

* The order of returned results is preserved. The execution order is NOT preserved. *

* Requires Server version 6.0+. * - * @param documents Documents to update. Must not be {@literal null}. + * @param documents The documents that identify the records to be updated. Must not be {@literal null}. * @return A Flux of the updated documents, otherwise onError is signalled with * {@link AerospikeException.BatchRecordArray} if batch update results contain errors, or with * {@link org.springframework.dao.DataAccessException} if batch operation failed. @@ -279,14 +279,14 @@ public interface ReactiveAerospikeOperations { Flux updateAll(Iterable documents); /** - * Reactively update documents using one batch request with a given set name. The policies are analogous to + * Reactively update records within the given set using one batch request. The policies are analogous to * {@link #update(Object)}. *

* The order of returned results is preserved. The execution order is NOT preserved. *

* Requires Server version 6.0+. * - * @param documents Documents to update. Must not be {@literal null}. + * @param documents The documents that identify the records to be updated. Must not be {@literal null}. * @param setName The set name to update the documents. * @return A Flux of the updated documents, otherwise onError is signalled with * {@link AerospikeException.BatchRecordArray} if batch update results contain errors, or with @@ -295,66 +295,65 @@ public interface ReactiveAerospikeOperations { Flux updateAll(Iterable documents, String setName); /** - * Reactively truncate/delete all the documents in the given entity's set. + * Reactively truncate/delete all records from the set determined by the given entityClass. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract the Aerospike set name from. Must not be {@literal null}. * @deprecated since 4.6.0, use deleteAll(Class entityClass) instead. */ Mono delete(Class entityClass); /** - * Reactively delete document by id, set name will be determined by the given entityClass. + * Reactively delete a record by id, set name will be determined by the given entity class. * - * @param id The id of the document to delete. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param id The id of a record to be deleted. Must not be {@literal null}. + * @param entityClass The class to extract the Aerospike set name from. Must not be {@literal null}. * @return A Mono of whether the document existed on server before deletion. * @deprecated since 4.6.0, use deleteById(Object id, Class entityClass) instead. */ Mono delete(Object id, Class entityClass); /** - * Reactively delete document. + * Reactively delete a record using the document's id. * - * @param document The document to delete. Must not be {@literal null}. + * @param document The document to get set name and id from. Must not be {@literal null}. * @return A Mono of whether the document existed on server before deletion. */ Mono delete(T document); /** - * Reactively delete document with a given set name. + * Reactively delete a record within the given set using the document's id. * - * @param document The document to delete. Must not be {@literal null}. - * @param setName Set name to delete the document. + * @param document The document to get id from. Must not be {@literal null}. + * @param setName Set name to use. * @return A Mono of whether the document existed on server before deletion. */ Mono delete(T document, String setName); /** - * Reactively delete document by id, set name will be determined by the given entityClass. + * Reactively delete a record by id, set name will be determined by the given entity class. * - * @param id The id of the document to delete. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param id The id of the record to be deleted. Must not be {@literal null}. + * @param entityClass The class to extract the Aerospike set name from. Must not be {@literal null}. * @return A Mono of whether the document existed on server before deletion. */ Mono deleteById(Object id, Class entityClass); /** - * Reactively delete document by id with a given set name. + * Reactively delete a record within the given set by id. * - * @param id The id of the document to delete. Must not be {@literal null}. - * @param setName Set name to delete the document. + * @param id The id of the record to be deleted. Must not be {@literal null}. + * @param setName Set name to use. * @return A Mono of whether the document existed on server before deletion. */ Mono deleteById(Object id, String setName); /** - * Reactively delete documents by providing multiple ids using a single batch delete operation, set name will be - * determined by the given entityClass. + * Reactively delete records using a single batch delete operation, set name will be determined by the given entity class. *

* This operation requires Server version 6.0+. * - * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param ids The ids of the records to find. Must not be {@literal null}. + * @param entityClass The class to extract the Aerospike set name from and to map the results to. Must not be * {@literal null}. * @return onError is signalled with {@link AerospikeException.BatchRecordArray} if batch delete results contain * errors, or with {@link org.springframework.dao.DataAccessException} if batch operation failed. @@ -362,26 +361,25 @@ public interface ReactiveAerospikeOperations { Mono deleteByIds(Iterable ids, Class entityClass); /** - * Reactively delete documents by providing multiple ids using a single batch delete operation with a given set - * name. + * Reactively delete records within the given set using a single batch delete operation. *

* This operation requires Server version 6.0+. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param setName Set name to delete the document. + * @param setName Set name to use. * @return onError is signalled with {@link AerospikeException.BatchRecordArray} if batch delete results contain * errors, or with {@link org.springframework.dao.DataAccessException} if batch operation failed. */ Mono deleteByIds(Iterable ids, String setName); /** - * Reactively delete documents by providing multiple ids using a single batch delete operation, set name will be + * Reactively delete records using a single batch delete operation, set name will be * determined by the given entityClass. *

* This operation requires Server version 6.0+. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract the Aerospike set name from and to map the results to. Must not be * {@literal null}. * @return onError is signalled with {@link AerospikeException.BatchRecordArray} if batch delete results contain * errors, or with {@link org.springframework.dao.DataAccessException} if batch operation failed. @@ -389,188 +387,167 @@ public interface ReactiveAerospikeOperations { Mono deleteByIds(Collection ids, Class entityClass); /** - * Reactively delete documents by providing multiple ids using a single batch delete operation with a given set - * name. + * Reactively delete records within the given set using a single batch delete operation. *

* This operation requires Server version 6.0+. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param setName Set name to delete the document. + * @param setName Set name to use. * @return onError is signalled with {@link AerospikeException.BatchRecordArray} if batch delete results contain * errors, or with {@link org.springframework.dao.DataAccessException} if batch operation failed. */ Mono deleteByIds(Collection ids, String setName); /** - * Executes a single batch delete for several entities. - *

- * Aerospike provides functionality to delete documents from different sets in 1 batch request. The methods allow to - * put grouped keys by entity type as parameter and get result as spring data aerospike entities grouped by entity - * type. + Reactively delete records from different sets in a single request. *

* This operation requires Server version 6.0+. * - * @param groupedKeys Must not be {@literal null}. + * @param groupedKeys Keys grouped by document type. Must not be {@literal null}. * @return onError is signalled with {@link AerospikeException.BatchRecordArray} if batch delete results contain * errors, or with {@link org.springframework.dao.DataAccessException} if batch operation failed. */ Mono deleteByIds(GroupedKeys groupedKeys); /** - * Reactively truncate/delete all the documents in the given entity's set. + * Reactively truncate/delete all records in the set determined by the given entity class. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. */ Mono deleteAll(Class entityClass); /** - * Reactively truncate/delete all the documents in the given entity's set. + * Reactively truncate/delete all the documents in the given set. * - * @param setName Set name to truncate/delete all the documents in. + * @param setName Set name to use. */ Mono deleteAll(String setName); /** - * Reactively add integer/double bin values to existing document bin values, read the new modified document and map - * it back the given document class type. + * Find an existing record matching the document's class and id, add map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the result to. Must not be * {@literal null}. - * @param values a Map of bin names and values to add. Must not be {@literal null}. - * @return A Mono of the modified document after add operations. + * @param values The Map of bin names and values to add. Must not be {@literal null}. + * @return A Mono of the modified record mapped to the document's class. */ Mono add(T document, Map values); /** - * Reactively add integer/double bin values to existing document bin values with a given set name, read the new - * modified document and map it back the given document class type. + * Find an existing record matching the document's id and the given set name, add map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get id from and to map the result to. Must not be * {@literal null}. - * @param setName Set name for the operation. - * @param values a Map of bin names and values to add. Must not be {@literal null}. - * @return A Mono of the modified document after add operations. + * @param setName Set name to use. + * @param values The Map of bin names and values to add. Must not be {@literal null}. + * @return A Mono of the modified record mapped to the document's class. */ Mono add(T document, String setName, Map values); /** - * Reactively add integer/double bin value to existing document bin value, read the new modified document and map it - * back the given document class type. + * Find an existing record matching the document's class and id, add specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the result to. Must not be * {@literal null}. * @param binName Bin name to use add operation on. Must not be {@literal null}. * @param value The value to add. - * @return A Mono of the modified document after add operation. + * @return A Mono of the modified record mapped to the document's class. */ Mono add(T document, String binName, long value); /** - * Reactively add integer/double bin value to existing document bin value with a given set name, read the new - * modified document and map it back the given document class type. + * Find an existing record matching the document's id and the given set name, add specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get id from and to map the result to. Must not be * {@literal null}. - * @param setName Set name for the operation. + * @param setName Set name to use. * @param binName Bin name to use add operation on. Must not be {@literal null}. * @param value The value to add. - * @return A Mono of the modified document after add operation. + * @return A Mono of the modified record mapped to the document's class. */ Mono add(T document, String setName, String binName, long value); /** - * Reactively append bin string values to existing document bin values, read the new modified document and map it - * back the given document class type. + * Find an existing record matching the document's class and id, append map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the result to. Must not be * {@literal null}. - * @param values a Map of bin names and values to append. Must not be {@literal null}. - * @return A Mono of the modified document after append operations. + * @param values The Map of bin names and values to append. Must not be {@literal null}. + * @return A Mono of the modified record mapped to the document's class. */ Mono append(T document, Map values); /** - * Reactively append bin string values to existing document bin values with a given set name, read the new modified - * document and map it back the given document class type. + * Find an existing record matching the document's id and the given set name, append map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be - * {@literal null}. - * @param setName Set name for the operation. - * @param values a Map of bin names and values to append. Must not be {@literal null}. - * @return A Mono of the modified document after append operations. + * @param document The document to get id from and to map the result to. Must not be {@literal null}. + * @param setName Set name to use. + * @param values The Map of bin names and values to append. Must not be {@literal null}. + * @return A Mono of the modified record mapped to the document's class. */ Mono append(T document, String setName, Map values); /** - * Reactively append bin string value to existing document bin value, read the new modified document and map it back - * the given document class type. + * Find an existing record matching the document's class and id, append specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the result to. Must not be * {@literal null}. * @param binName Bin name to use append operation on. * @param value The value to append. - * @return A Mono of the modified document after append operation. + * @return A Mono of the modified record mapped to the document's class. */ Mono append(T document, String binName, String value); /** - * Reactively append bin string value to existing document bin value with a given set name, read the new modified - * document and map it back the given document class type. + * Find an existing record matching the document's id and the given set name, append specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be - * {@literal null}. + * @param document The document to get id from and to map the result to. Must not be {@literal null}. + * @param setName Set name to use. * @param binName Bin name to use append operation on. - * @param setName Set name for the operation. * @param value The value to append. - * @return A Mono of the modified document after append operation. + * @return A Mono of the modified record mapped to the document's class. */ Mono append(T document, String setName, String binName, String value); /** - * Reactively prepend bin string values to existing document bin values, read the new modified document and map it - * back the given document class type. + * Find an existing record matching the document's class and id, prepend map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the result to. Must not be * {@literal null}. - * @param values a Map of bin names and values to prepend. Must not be {@literal null}. - * @return A Mono of the modified document after prepend operations. + * @param values The Map of bin names and values to prepend. Must not be {@literal null}. + * @return A Mono of the modified record mapped to the document's class. */ Mono prepend(T document, Map values); /** - * Reactively prepend bin string values to existing document bin values with a given set name, read the new modified - * document and map it back the given document class type. + * Find an existing record matching the document's id and the given set name, prepend map values to the corresponding bins of the record and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be - * {@literal null}. - * @param setName Set name for the operation. - * @param values a Map of bin names and values to prepend. Must not be {@literal null}. - * @return A Mono of the modified document after prepend operations. + * @param document The document to get id from and to map the result to. Must not be {@literal null}. + * @param setName Set name to use. + * @param values The Map of bin names and values to prepend. Must not be {@literal null}. + * @return A Mono of the modified record mapped to the document's class. */ Mono prepend(T document, String setName, Map values); /** - * Reactively prepend bin string value to existing document bin value, read the new modified document and map it - * back the given document class type. + * Find an existing record matching the document's class and id, prepend specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be + * @param document The document to get set name and id from and to map the result to. Must not be * {@literal null}. * @param binName Bin name to use prepend operation on. * @param value The value to prepend. - * @return A Mono of the modified document after prepend operation. + * @return A Mono of the modified record mapped to the document's class. */ Mono prepend(T document, String binName, String value); /** - * Reactively prepend bin string value to existing document bin value with a given set name, read the new modified - * document and map it back the given document class type. + * Find an existing record matching the document's id and the given set name, prepend specified value to the record's bin and return the modified record mapped to the document's class. * - * @param document The document to extract the Aerospike set from and to map the documents to. Must not be - * {@literal null}. + * @param document The document to get id from and to map the result to. Must not be {@literal null}. + * @param setName Set name to use. * @param binName Bin name to use prepend operation on. - * @param setName Set name for the operation. * @param value The value to prepend. - * @return A Mono of the modified document after prepend operation. + * @return A Mono of the modified record mapped to the document's class. */ Mono prepend(T document, String setName, String binName, String value); @@ -583,144 +560,143 @@ public interface ReactiveAerospikeOperations { Mono execute(Supplier supplier); /** - * Reactively find a document by id, set name will be determined by the given entityClass. + * Reactively find a record by id, set name will be determined by the given entityClass. *

- * Document will be mapped to the given entityClass. + * The record will be mapped to the given entityClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the document to. Must not be + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to extract set name from and to map the document to. Must not be * {@literal null}. - * @return A Mono of the matching document, returned document will be mapped to entityClass's type. + * @return A Mono of the matching record mapped to entityClass type. */ Mono findById(Object id, Class entityClass); /** - * Reactively find a document by id with a given set name. + * Reactively find a record by id within the given set. *

- * Document will be mapped to the given entityClass. + * The record will be mapped to the given entityClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to map the document to and to get entity properties from (such expiration). Must not + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to map the record to and to get entity properties from (such expiration). Must not * be {@literal null}. - * @param setName Set name to find the document from. - * @return A Mono of the matching document, returned document will be mapped to entityClass's type. + * @param setName Set name to use. + * @return A Mono of the matching record mapped to entityClass type. */ Mono findById(Object id, Class entityClass, String setName); /** - * Reactively find a document by id, set name will be determined by the given entityClass. + * Reactively find a record by id, set name will be determined by the given entityClass. *

- * Document will be mapped to the given targetClass. + * The record will be mapped to the given targetClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A Mono of the matching document, returned document will be mapped to targetClass's type. + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Mono of the matching record mapped to targetClass type. */ Mono findById(Object id, Class entityClass, Class targetClass); /** - * Reactively find a document by id with a given set name. + * Reactively find a record by id within the given set. *

- * Document will be mapped to the given targetClass. + * The record will be mapped to the given targetClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to map the document to and to get entity properties from (such expiration). Must not + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to map the record to and to get entity properties from (such expiration). Must not * be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @param setName Set name to find the document from. - * @return A Mono of the matching document, returned document will be mapped to targetClass's type. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @param setName Set name to use. + * @return A Mono of the matching record mapped to targetClass type. */ Mono findById(Object id, Class entityClass, Class targetClass, String setName); /** - * Reactively find documents by providing multiple ids using a single batch read operation, set name will be + * Reactively find records by ids using a single batch read operation, set name will be * determined by the given entityClass. *

- * Documents will be mapped to the given entityClass. + * The records will be mapped to the given entityClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract set name from and to map the documents to. Must not be * {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to entityClass's type. + * @return A Flux of matching records mapped to entityClass type. */ Flux findByIds(Iterable ids, Class entityClass); /** - * Reactively find documents by providing multiple ids using a single batch read operation, set name will be + * Reactively find records by ids using a single batch read operation, set name will be * determined by the given entityClass. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param targetClass The class to map the documents to. Must not be {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to targetClass's type. + * @return A Flux of matching records mapped to targetClass type. */ Flux findByIds(Iterable ids, Class entityClass, Class targetClass); /** - * Reactively find documents by providing multiple ids using a single batch read operation with a given set name. + * Reactively find records by ids within the given set using a single batch read operation. *

- * Documents will be mapped to the given entityClass. + * The records will be mapped to the given entityClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. * @param targetClass The class to map the documents to. Must not be {@literal null}. - * @param setName Set name to find the documents from. - * @return A Flux of matching documents, returned documents will be mapped to entityClass's type. + * @param setName Set name to use. + * @return A Flux of matching records mapped to entityClass type. */ Flux findByIds(Iterable ids, Class targetClass, String setName); /** - * Reactively executes a single batch request to get results for several entities. + * Reactively execute a single batch request to find several records, possibly from different sets. *

- * Aerospike provides functionality to get documents from different sets in 1 batch request. The methods allow to - * put grouped keys by entity type as parameter and get result as spring data aerospike entities grouped by entity - * type. + * Aerospike provides functionality to get records from different sets in 1 batch request. This method receives + * keys grouped by document type as a parameter and returns Aerospike records mapped to documents grouped by type. * * @param groupedKeys Must not be {@literal null}. - * @return Mono of grouped entities. + * @return Mono of grouped documents. */ Mono findByIds(GroupedKeys groupedKeys); /** - * Find document by providing id, set name will be determined by the given entityClass. + * Find a record by id using a query, set name will be determined by the given entityClass. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * - * @param id The id of the document to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. + * @param id The id of the record to find. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. * @param query The {@link Query} to filter results. Optional argument (null if no filtering required). - * @return The document from Aerospike, returned document will be mapped to targetClass's type. + * @return The matching record mapped to targetClass's type. */ Mono findByIdUsingQuery(Object id, Class entityClass, Class targetClass, @Nullable Query query); /** - * Find document by providing id with a given set name. + * Find a record by id within the given set using a query. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * - * @param id The id of the document to find. Must not be {@literal null}. + * @param id The id of the record to find. Must not be {@literal null}. * @param entityClass The class to get the entity properties from (such as expiration). Must not be * {@literal null}. - * @param targetClass The class to map the document to. - * @param setName Set name to find the document from. + * @param targetClass The class to map the record to. + * @param setName Set name to use. * @param query The {@link Query} to filter results. Optional argument (null if no filtering required). - * @return The document from Aerospike, returned document will be mapped to targetClass's type. + * @return The matching record mapped to targetClass's type. */ Mono findByIdUsingQuery(Object id, Class entityClass, Class targetClass, String setName, @Nullable Query query); /** - * Find documents by providing multiple ids, set name will be determined by the given entityClass. + * Find records by ids, set name will be determined by the given entityClass. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. * @param query The {@link Query} to filter results. Optional argument (null if no filtering required). * @return The documents from Aerospike, returned documents will be mapped to targetClass's type if provided * (otherwise to entityClass's type), if no document exists, an empty list is returned. @@ -729,15 +705,15 @@ Flux findByIdsUsingQuery(Collection ids, Class entityClass, Clas @Nullable Query query); /** - * Find documents by providing multiple ids with a given set name. + * Find records by ids within the given set name. *

- * Documents will be mapped to the given targetClass. + * The records will be mapped to the given targetClass. * * @param ids The ids of the documents to find. Must not be {@literal null}. * @param entityClass The class to get the entity properties from (such as expiration). Must not be * {@literal null}. - * @param targetClass The class to map the document to. - * @param setName Set name to find the document from. + * @param targetClass The class to map the record to. + * @param setName Set name to use. * @param query The {@link Query} to filter results. Optional argument (null if no filtering required). * @return The documents from Aerospike, returned documents will be mapped to targetClass's type if provided * (otherwise to entityClass's type), if no document exists, an empty list is returned. @@ -746,90 +722,90 @@ Flux findByIdsUsingQuery(Collection ids, Class entityClass, Clas @Nullable Query query); /** - * Reactively find documents in the given entityClass's set using a query and map them to the given class type. + * Reactively find records in the given entityClass's set using a query and map them to the given class type. * * @param query The {@link Query} to filter results. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract set name from and to map the documents to. Must not be * {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to entityClass's type. + * @return A Flux of matching records mapped to entityClass type. */ Flux find(Query query, Class entityClass); /** - * Reactively find documents in the given entityClass's set using a query and map them to the given target class + * Reactively find records in the given entityClass's set using a query and map them to the given target class * type. * * @param query The {@link Query} to filter results. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to targetClass's type. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Flux of matching records mapped to targetClass type. */ Flux find(Query query, Class entityClass, Class targetClass); /** - * Reactively find documents in the given set using a query and map them to the given target class type. + * Reactively find records in the given set using a query and map them to the given target class type. * * @param query The {@link Query} to filter results. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @param setName Set name to find the documents from. - * @return A Flux of matching documents, returned documents will be mapped to targetClass's type. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @param setName Set name to use. + * @return A Flux of matching records mapped to targetClass type. */ Flux find(Query query, Class targetClass, String setName); /** - * Reactively find all documents in the given entityClass's set and map them to the given class type. + * Reactively find all records in the given entityClass's set and map them to the given class type. * - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract set name from and to map the documents to. Must not be * {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to entityClass's type. + * @return A Flux of matching records mapped to entityClass type. */ Flux findAll(Class entityClass); /** - * Reactively find all documents in the given entityClass's set and map them to the given target class type. + * Reactively find all records in the given entityClass's set and map them to the given target class type. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to targetClass's type. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Flux of matching records mapped to targetClass type. */ Flux findAll(Class entityClass, Class targetClass); /** - * Reactively find all documents in the given set and map them to the given class type. + * Reactively find all records in the given set and map them to the given class type. * * @param targetClass The class to map the documents to. Must not be {@literal null}. * @param setName The set name to find the document. - * @return A Flux of matching documents, returned documents will be mapped to entityClass's type. + * @return A Flux of matching records mapped to entityClass type. */ Flux findAll(Class targetClass, String setName); /** - * Reactively find all documents in the given entityClass's set using a provided sort and map them to the given + * Reactively find all records in the given entityClass's set using a provided sort and map them to the given * class type. * * @param sort The sort to affect the returned iterable documents order. * @param offset The offset to start the range from. * @param limit The limit of the range. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. - * @return A Flux of matching documents, returned documents will be mapped to entityClass's type. + * @param entityClass The class to extract set name from and to map the documents to. + * @return A Flux of matching records mapped to entityClass type. */ Flux findAll(Sort sort, long offset, long limit, Class entityClass); /** - * Reactively find all documents in the given entityClass's set using a provided sort and map them to the given + * Reactively find all records in the given entityClass's set using a provided sort and map them to the given * target class type. * * @param sort The sort to affect the returned iterable documents order. * @param offset The offset to start the range from. * @param limit The limit of the range. - * @param entityClass The class to extract the Aerospike set from. + * @param entityClass The class to extract set name from. * @param targetClass The class to map the documents to. Must not be {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to targetClass's type. + * @return A Flux of matching records mapped to targetClass type. */ Flux findAll(Sort sort, long offset, long limit, Class entityClass, Class targetClass); /** - * Reactively find all documents in the given entityClass's set using a provided sort and map them to the given + * Reactively find all records in the given entityClass's set using a provided sort and map them to the given * target class type. * * @param sort The sort to affect the returned iterable documents order. @@ -837,139 +813,137 @@ Flux findByIdsUsingQuery(Collection ids, Class entityClass, Clas * @param limit The limit of the range. * @param targetClass The class to map the documents to. Must not be {@literal null}. * @param setName The set name to find the documents. - * @return A Flux of matching documents, returned documents will be mapped to targetClass's type. + * @return A Flux of matching records mapped to targetClass type. */ Flux findAll(Sort sort, long offset, long limit, Class targetClass, String setName); /** - * Reactively find documents in the given entityClass's set using a range (offset, limit) and a sort and map them to + * Reactively find records in the given entityClass's set using a range (offset, limit) and a sort and map them to * the given class type. * * @param offset The offset to start the range from. * @param limit The limit of the range. * @param sort The sort to affect the order of the returned Stream of documents. - * @param entityClass The class to extract the Aerospike set from and to map the documents to. Must not be + * @param entityClass The class to extract set name from and to map the documents to. Must not be * {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to entityClass's type. + * @return A Flux of matching records mapped to entityClass type. */ Flux findInRange(long offset, long limit, Sort sort, Class entityClass); /** - * Reactively find documents in the given set using a range (offset, limit) and a sort and map them to the given + * Reactively find records in the given set using a range (offset, limit) and a sort and map them to the given * class type. * * @param offset The offset to start the range from. * @param limit The limit of the range. * @param sort The sort to affect the order of the returned Stream of documents. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @param setName Set name to find the documents from. - * @return A Flux of matching documents, returned documents will be mapped to entityClass's type. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @param setName Set name to use. + * @return A Flux of matching records mapped to entityClass type. */ Flux findInRange(long offset, long limit, Sort sort, Class targetClass, String setName); /** - * Reactively find documents in the given entityClass's set using a range (offset, limit) and a sort and map them to + * Reactively find records in the given entityClass's set using a range (offset, limit) and a sort and map them to * the given target class type. * * @param offset The offset to start the range from. * @param limit The limit of the range. * @param sort The sort to affect the returned Stream of documents order. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. Must not be {@literal null}. - * @return A Flux of matching documents, returned documents will be mapped to targetClass's type. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. Must not be {@literal null}. + * @return A Flux of matching records mapped to targetClass type. */ Flux findInRange(long offset, long limit, Sort sort, Class entityClass, Class targetClass); /** - * Reactively find documents in the given entityClass's set using a query and map them to the given target class + * Reactively find records in the given entityClass's set using a query and map them to the given target class * type. If the query has pagination and/or sorting, post-processing must be applied separately. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @param targetClass The class to map the document to. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @param targetClass The class to map the record to. * @param query The {@link Query} to filter results. - * @return A Flux of all matching documents regardless of pagination/sorting, returned documents will be mapped to - * targetClass's type. + * @return A Flux of all matching records mapped to + * targetClass type (regardless of pagination/sorting). */ Flux findUsingQueryWithoutPostProcessing(Class entityClass, Class targetClass, Query query); /** - * Reactively check if document exists by providing document id and entityClass (set name will be determined by the - * given entityClass). + * Reactively check by id if a record exists within the set associated with the given entityClass. * - * @param id The id to check if exists. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return A Mono of whether the document exists. + * @param id The id to check for record existence. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @return A Mono of whether the record exists. */ Mono exists(Object id, Class entityClass); /** - * Reactively check if document exists by providing document id with a given set name. + * Reactively check by id if a record exists within the given set name. * - * @param id The id to check if exists. Must not be {@literal null}. - * @param setName Set name to check if document exists. - * @return A Mono of whether the document exists. + * @param id The id to check for record existence. Must not be {@literal null}. + * @param setName Set name to use. + * @return A Mono of whether the record exists. */ Mono exists(Object id, String setName); /** - * Reactively check if any document exists by defining a query and entityClass (set name will be determined by the - * given entityClass). + * Reactively check using a query if any matching records exist within the set determined by the given entityClass. * * @param query The query to check if any returned document exists. Must not be {@literal null}. - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return A Mono of whether the document exists. + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @return A Mono of whether matching records exist. */ Mono existsByQuery(Query query, Class entityClass); /** - * Reactively check if any document exists by defining a query, entityClass and a given set name. + * Reactively check using a query if any matching records exist within the given set. * - * @param query The query to check if any returned document exists. Must not be {@literal null}. - * @param entityClass The class to translate to returned results into. Must not be {@literal null}. - * @param setName The set name to check if documents exists in. Must not be {@literal null}. - * @return A Mono of whether the document exists. + * @param query The query to check if any matching records exist. Must not be {@literal null}. + * @param entityClass The class to translate to returned records into. Must not be {@literal null}. + * @param setName Set name to use. Must not be {@literal null}. + * @return A Mono of whether matching records exist. */ Mono existsByQuery(Query query, Class entityClass, String setName); /** - * Reactively return the amount of documents in the given entityClass's Aerospike set. + * Reactively return the amount of records in the set determined by the given entityClass. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return A Mono of the amount of documents in the set (of the given entityClass). + * @param entityClass The class to extract set name from. Must not be {@literal null}. + * @return A Mono of the amount of records in the set (of the given entityClass). */ Mono count(Class entityClass); /** - * Reactively return the amount of documents in the given Aerospike set. + * Reactively return the amount of records in the given Aerospike set. * * @param setName The name of the set to count. Must not be {@literal null}. - * @return A Mono of the amount of documents in the given set. + * @return A Mono of the amount of records in the given set. */ Mono count(String setName); /** - * Reactively return the amount of documents in a query results. set name will be determined by the given + * Reactively return the amount of records in query results. Set name will be determined by the given * entityClass. * * @param query The query that provides the result set for count. - * @param entityClass entityClass The class to extract the Aerospike set from. Must not be {@literal null}. - * @return A Mono of the amount of documents that the given query and entity class supplied. + * @param entityClass entityClass to extract set name from. Must not be {@literal null}. + * @return A Mono of the amount of records matching the given query and entity class. */ Mono count(Query query, Class entityClass); /** - * Reactively return the amount of documents in a query results with a given set name. + * Reactively return the amount of records in query results within the given set. * * @param query The query that provides the result set for count. * @param setName The name of the set to count. Must not be {@literal null}. - * @return A Mono of the amount of documents that the given query and set name. + * @return A Mono of the amount of records matching the given query and set name. */ Mono count(Query query, String setName); /** - * Reactively create index by specified name in Aerospike. + * Reactively create an index with the specified name in Aerospike. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -978,9 +952,9 @@ Mono createIndex(Class entityClass, String indexName, String binName, IndexType indexType); /** - * Reactively create index by specified name in Aerospike. + * Reactively create an index with the specified name in Aerospike. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -990,9 +964,9 @@ Mono createIndex(Class entityClass, String indexName, String binNam IndexType indexType, IndexCollectionType indexCollectionType); /** - * Reactively create index by specified name in Aerospike. + * Reactively create an index with the specified name in Aerospike. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1003,9 +977,9 @@ Mono createIndex(Class entityClass, String indexName, String binNam IndexType indexType, IndexCollectionType indexCollectionType, CTX... ctx); /** - * Reactively create index by specified name in Aerospike. + * Reactively create an index with the specified name in Aerospike. * - * @param setName Set name to create the index. + * @param setName Set name to use. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1014,9 +988,9 @@ Mono createIndex(String setName, String indexName, String binName, IndexType indexType); /** - * Reactively create index by specified name in Aerospike. + * Reactively create an index with the specified name in Aerospike. * - * @param setName Set name to create the index. + * @param setName Set name to use. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. @@ -1026,30 +1000,30 @@ Mono createIndex(String setName, String indexName, String binName, IndexType indexType, IndexCollectionType indexCollectionType); /** - * Reactively create index by specified name in Aerospike. + * Reactively create an index with the specified name in Aerospike. * - * @param setName Set name to create the index. + * @param setName Set name to use. * @param indexName The index name. Must not be {@literal null}. * @param binName The bin name to create the index on. Must not be {@literal null}. * @param indexType The type of the index. Must not be {@literal null}. * @param indexCollectionType The collection type of the index. Must not be {@literal null}. - * @param ctx optional context to index on elements within a CDT. + * @param ctx Optional context to index elements within a CDT. */ Mono createIndex(String setName, String indexName, String binName, IndexType indexType, IndexCollectionType indexCollectionType, CTX... ctx); /** - * Reactively delete index by specified name from Aerospike. + * Reactively delete an index with the specified name in Aerospike. * - * @param entityClass The class to extract the Aerospike set from. Must not be {@literal null}. + * @param entityClass The class to extract set name from. Must not be {@literal null}. * @param indexName The index name. Must not be {@literal null}. */ Mono deleteIndex(Class entityClass, String indexName); /** - * Reactively delete index by specified name from Aerospike. + * Reactively delete an index with the specified name within the given set in Aerospike. * - * @param setName Set name to delete the index from. + * @param setName Set name to use. * @param indexName The index name. Must not be {@literal null}. */ Mono deleteIndex(String setName, String indexName); diff --git a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateDeleteTests.java b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateDeleteTests.java index e47403bff..4a78eb165 100644 --- a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateDeleteTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateDeleteTests.java @@ -47,7 +47,7 @@ public void deleteByObject_ignoresDocumentVersionEvenIfDefaultGenerationPolicyIs try { VersionedClass initialDocument = new VersionedClass(id, "a"); template.insert(initialDocument); - template.update(new VersionedClass(id, "b", initialDocument.version)); + template.update(new VersionedClass(id, "b", initialDocument.getVersion())); boolean deleted = template.delete(initialDocument); assertThat(deleted).isTrue(); diff --git a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateFindByIdTests.java b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateFindByIdTests.java index badf29b77..5fd524318 100644 --- a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateFindByIdTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateFindByIdTests.java @@ -45,10 +45,10 @@ public class AerospikeTemplateFindByIdTests extends BaseBlockingIntegrationTests public void findById_shouldReadVersionedClassWithAllArgsConstructor() { VersionedClassWithAllArgsConstructor inserted = new VersionedClassWithAllArgsConstructor(id, "foobar", 0L); template.insert(inserted); - assertThat(template.findById(id, VersionedClassWithAllArgsConstructor.class).version).isEqualTo(1L); - template.update(new VersionedClassWithAllArgsConstructor(id, "foobar1", inserted.version)); + assertThat(template.findById(id, VersionedClassWithAllArgsConstructor.class).getVersion()).isEqualTo(1L); + template.update(new VersionedClassWithAllArgsConstructor(id, "foobar1", inserted.getVersion())); VersionedClassWithAllArgsConstructor result = template.findById(id, VersionedClassWithAllArgsConstructor.class); - assertThat(result.version).isEqualTo(2L); + assertThat(result.getVersion()).isEqualTo(2L); template.delete(result); // cleanup } @@ -56,11 +56,13 @@ public void findById_shouldReadVersionedClassWithAllArgsConstructor() { public void findById_shouldReadVersionedClassWithAllArgsConstructorAndSetName() { VersionedClassWithAllArgsConstructor inserted = new VersionedClassWithAllArgsConstructor(id, "foobar", 0L); template.insert(inserted, OVERRIDE_SET_NAME); - assertThat(template.findById(id, VersionedClassWithAllArgsConstructor.class, OVERRIDE_SET_NAME).version).isEqualTo(1L); - template.update(new VersionedClassWithAllArgsConstructor(id, "foobar1", inserted.version), OVERRIDE_SET_NAME); + assertThat(template.findById(id, VersionedClassWithAllArgsConstructor.class, OVERRIDE_SET_NAME) + .getVersion()).isEqualTo(1L); + template.update(new VersionedClassWithAllArgsConstructor(id, "foobar1", inserted.getVersion()), + OVERRIDE_SET_NAME); VersionedClassWithAllArgsConstructor result = template.findById(id, VersionedClassWithAllArgsConstructor.class, OVERRIDE_SET_NAME); - assertThat(result.version).isEqualTo(2L); + assertThat(result.getVersion()).isEqualTo(2L); template.delete(result, OVERRIDE_SET_NAME); // cleanup } diff --git a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateInsertTests.java b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateInsertTests.java index 8c1bd5dd7..1197af2b7 100644 --- a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateInsertTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateInsertTests.java @@ -135,7 +135,7 @@ public void insertsDocumentWithZeroVersionIfThereIsNoDocumentWithSameKey() { public void insertsDocumentWithVersionGreaterThanZeroIfThereIsNoDocumentWithSameKey() { VersionedClass document = new VersionedClass(id, "any", 5L); // initially given versions are ignored - // RecordExistsAction.CREATE_ONLY is set + // RecordExistsAction.CREATE_ONLY is used template.insert(document); assertThat(document.getVersion()).isEqualTo(1); @@ -271,12 +271,10 @@ public void shouldInsertAllVersionedDocuments() { VersionedClass first = new VersionedClass(id, "foo"); VersionedClass second = new VersionedClass(nextId(), "foo", 1L); VersionedClass third = new VersionedClass(nextId(), "foo", 2L); - template.insertAll(List.of(first)); // initially given versions are ignored - // RecordExistsAction.CREATE_ONLY is set - assertThatNoException().isThrownBy(() -> template.insertAll( - List.of(second, third))); + // RecordExistsAction.CREATE_ONLY is used + assertThatNoException().isThrownBy(() -> template.insertAll(List.of(first, second, third))); assertThat(first.getVersion() == 1).isTrue(); assertThat(second.getVersion() == 1).isTrue(); diff --git a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateSaveTests.java b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateSaveTests.java index d44202a35..9b16c64a8 100644 --- a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateSaveTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateSaveTests.java @@ -105,8 +105,8 @@ public void shouldSaveAndSetVersion() { VersionedClass first = new VersionedClass(id, "foo"); template.save(first); - assertThat(first.version).isEqualTo(1); - assertThat(template.findById(id, VersionedClass.class).version).isEqualTo(1); + assertThat(first.getVersion()).isEqualTo(1); + assertThat(template.findById(id, VersionedClass.class).getVersion()).isEqualTo(1); } @Test @@ -128,7 +128,7 @@ public void shouldUpdateNotVersionedDocumentIfItAlreadyExists() { @Test public void shouldSaveDocumentWithEqualVersion() { - // if an object has version property, GenerationPolicy.EXPECT_GEN_EQUAL is set + // if an object has version property, GenerationPolicy.EXPECT_GEN_EQUAL is used VersionedClass first = new VersionedClass(id, "foo", 0L); VersionedClass second = new VersionedClass(id, "foo", 1L); VersionedClass third = new VersionedClass(id, "foo", 2L); @@ -168,7 +168,7 @@ public void shouldUpdateNullFieldForClassWithVersionField() { assertThat(byId.getField()) .isEqualTo("field"); - template.save(new VersionedClass(id, null, byId.version)); + template.save(new VersionedClass(id, null, byId.getVersion())); assertThat(template.findById(id, VersionedClass.class).getField()) .isNull(); @@ -195,11 +195,11 @@ public void shouldUpdateExistingDocument() { VersionedClass one = new VersionedClass(id, "foo"); template.save(one); - template.save(new VersionedClass(id, "foo1", one.version)); + template.save(new VersionedClass(id, "foo1", one.getVersion())); VersionedClass value = template.findById(id, VersionedClass.class); - assertThat(value.version).isEqualTo(2); - assertThat(value.field).isEqualTo("foo1"); + assertThat(value.getVersion()).isEqualTo(2); + assertThat(value.getField()).isEqualTo("foo1"); } @Test @@ -209,7 +209,7 @@ public void shouldSetVersionWhenSavingTheSameDocument() { template.save(one); template.save(one); - assertThat(one.version).isEqualTo(3); + assertThat(one.getVersion()).isEqualTo(3); } @Test @@ -219,14 +219,14 @@ public void shouldUpdateAlreadyExistingDocument() { VersionedClass initial = new VersionedClass(id, "value-0"); template.save(initial); - assertThat(initial.version).isEqualTo(1); + assertThat(initial.getVersion()).isEqualTo(1); AsyncUtils.executeConcurrently(numberOfConcurrentSaves, () -> { boolean saved = false; while (!saved) { long counterValue = counter.incrementAndGet(); VersionedClass messageData = template.findById(id, VersionedClass.class); - messageData.field = "value-" + counterValue; + messageData.setField("value-" + counterValue); try { template.save(messageData); saved = true; @@ -237,9 +237,9 @@ public void shouldUpdateAlreadyExistingDocument() { VersionedClass actual = template.findById(id, VersionedClass.class); - assertThat(actual.field).isNotEqualTo(initial.field); - assertThat(actual.version).isNotEqualTo(initial.version) - .isEqualTo(initial.version + numberOfConcurrentSaves); + assertThat(actual.getField()).isNotEqualTo(initial.getField()); + assertThat(actual.getVersion()).isNotEqualTo(initial.getVersion()) + .isEqualTo(initial.getVersion() + numberOfConcurrentSaves); } @Test @@ -330,17 +330,22 @@ public void shouldSaveAndFindDocumentWithByteArrayField() { @Test public void shouldSaveAllAndSetVersion() { VersionedClass first = new VersionedClass(id, "foo"); - VersionedClass second = new VersionedClass(nextId(), "foo"); + VersionedClass second = new VersionedClass(nextId(), "bar"); + + template.save(second); + assertThat(second.getVersion()).isEqualTo(1); + second.setVersion(second.getVersion()); + // batch write operations are supported starting with Server version 6.0+ if (ServerVersionUtils.isBatchWriteSupported(client)) { template.saveAll(List.of(first, second)); } else { - List.of(first, second).forEach(person -> template.save(person)); + List.of(first, second).forEach(document -> template.save(document)); } - assertThat(first.version).isEqualTo(1); - assertThat(second.version).isEqualTo(1); - assertThat(template.findById(id, VersionedClass.class).version).isEqualTo(1); + assertThat(first.getVersion()).isEqualTo(1); + assertThat(second.getVersion()).isEqualTo(2); + assertThat(template.findById(id, VersionedClass.class).getVersion()).isEqualTo(1); template.delete(first); // cleanup template.delete(second); // cleanup } @@ -356,9 +361,9 @@ public void shouldSaveAllAndSetVersionWithSetName() { List.of(first, second).forEach(person -> template.save(person, OVERRIDE_SET_NAME)); } - assertThat(first.version).isEqualTo(1); - assertThat(second.version).isEqualTo(1); - assertThat(template.findById(id, VersionedClass.class, OVERRIDE_SET_NAME).version).isEqualTo(1); + assertThat(first.getVersion()).isEqualTo(1); + assertThat(second.getVersion()).isEqualTo(1); + assertThat(template.findById(id, VersionedClass.class, OVERRIDE_SET_NAME).getVersion()).isEqualTo(1); template.delete(first, OVERRIDE_SET_NAME); // cleanup template.delete(second, OVERRIDE_SET_NAME); // cleanup } @@ -370,6 +375,9 @@ public void shouldSaveAllVersionedDocumentsAndSetVersionAndThrowExceptionIfAlrea VersionedClass first = new VersionedClass(id, "foo"); VersionedClass second = new VersionedClass(nextId(), "foo"); + assertThat(first.getVersion() == 0).isTrue(); + assertThat(second.getVersion() == 0).isTrue(); + assertThatThrownBy(() -> template.saveAll(List.of(first, first, second, second))) .isInstanceOf(AerospikeException.BatchRecordArray.class) .hasMessageContaining("Errors during batch save"); @@ -386,13 +394,22 @@ public void shouldSaveAllVersionedDocumentsAndSetVersionAndThrowExceptionIfAlrea public void shouldSaveAllNotVersionedDocumentsIfAlreadyExist() { // batch write operations are supported starting with Server version 6.0+ if (ServerVersionUtils.isBatchWriteSupported(client)) { + Person john = new Person("id1", "John"); + Person jack = new Person("id2", "Jack"); + template.save(jack); // saving non-versioned document to create a new DB record + // If an object has no version property, RecordExistsAction.UPDATE is used + // If a corresponding record does not exist it will be created, otherwise updated (an "upsert") + template.saveAll(List.of(john, jack)); + assertThat(template.findById("id1", Person.class)).isEqualTo(john); // DB record is created + assertThat(template.findById("id2", Person.class)).isEqualTo(jack); + template.delete(john); // cleanup + template.delete(jack); // cleanup + Person person = new Person(id, "Amol"); person.setAge(28); template.save(person); - - // If an object has no version property, RecordExistsAction.UPDATE is set + // If an object has no version property, RecordExistsAction.UPDATE is used assertThatNoException().isThrownBy(() -> template.saveAll(List.of(person, person))); - template.delete(person); // cleanup } } diff --git a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateUpdateTests.java b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateUpdateTests.java index 96c53a36c..2b0b1c76e 100644 --- a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateUpdateTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateUpdateTests.java @@ -132,7 +132,8 @@ public void updateSpecificFieldsWithFieldAnnotatedPropertyAndSetName() { List fields = new ArrayList<>(); fields.add("age"); fields.add("emailAddress"); - template.update(Person.builder().id(id).age(41).emailAddress("andrew2@gmail.com").build(), OVERRIDE_SET_NAME, fields); + template.update(Person.builder().id(id).age(41).emailAddress("andrew2@gmail.com") + .build(), OVERRIDE_SET_NAME, fields); assertThat(template.findById(id, Person.class, OVERRIDE_SET_NAME)).satisfies(doc -> { assertThat(doc.getFirstName()).isEqualTo("Andrew"); @@ -167,21 +168,21 @@ public void updateSpecificFieldsWithFieldAnnotatedPropertyActualValue() { public void updatesFieldValueAndDocumentVersion() { VersionedClass document = new VersionedClass(id, "foobar"); template.insert(document); - assertThat(template.findById(id, VersionedClass.class).version).isEqualTo(1); + assertThat(template.findById(id, VersionedClass.class).getVersion()).isEqualTo(1); - document = new VersionedClass(id, "foobar1", document.version); + document = new VersionedClass(id, "foobar1", document.getVersion()); template.update(document); assertThat(template.findById(id, VersionedClass.class)).satisfies(doc -> { - assertThat(doc.field).isEqualTo("foobar1"); - assertThat(doc.version).isEqualTo(2); + assertThat(doc.getField()).isEqualTo("foobar1"); + assertThat(doc.getVersion()).isEqualTo(2); }); - document = new VersionedClass(id, "foobar2", document.version); + document = new VersionedClass(id, "foobar2", document.getVersion()); template.update(document); VersionedClass result = template.findById(id, VersionedClass.class); assertThat(result).satisfies(doc -> { - assertThat(doc.field).isEqualTo("foobar2"); - assertThat(doc.version).isEqualTo(3); + assertThat(doc.getField()).isEqualTo("foobar2"); + assertThat(doc.getVersion()).isEqualTo(3); }); template.delete(result); // cleanup } @@ -190,23 +191,23 @@ public void updatesFieldValueAndDocumentVersion() { public void updateSpecificFieldsWithDocumentVersion() { VersionedClass document = new VersionedClass(id, "foobar"); template.insert(document); - assertThat(template.findById(id, VersionedClass.class).version).isEqualTo(1); + assertThat(template.findById(id, VersionedClass.class).getVersion()).isEqualTo(1); - document = new VersionedClass(id, "foobar1", document.version); + document = new VersionedClass(id, "foobar1", document.getVersion()); List fields = new ArrayList<>(); fields.add("field"); template.update(document, fields); assertThat(template.findById(id, VersionedClass.class)).satisfies(doc -> { - assertThat(doc.field).isEqualTo("foobar1"); - assertThat(doc.version).isEqualTo(2); + assertThat(doc.getField()).isEqualTo("foobar1"); + assertThat(doc.getVersion()).isEqualTo(2); }); - document = new VersionedClass(id, "foobar2", document.version); + document = new VersionedClass(id, "foobar2", document.getVersion()); template.update(document, fields); VersionedClass result = template.findById(id, VersionedClass.class); assertThat(result).satisfies(doc -> { - assertThat(doc.field).isEqualTo("foobar2"); - assertThat(doc.version).isEqualTo(3); + assertThat(doc.getField()).isEqualTo("foobar2"); + assertThat(doc.getVersion()).isEqualTo(3); }); template.delete(result); // cleanup } @@ -216,12 +217,12 @@ public void updatesFieldToNull() { VersionedClass document = new VersionedClass(id, "foobar"); template.insert(document); - document = new VersionedClass(id, null, document.version); + document = new VersionedClass(id, null, document.getVersion()); template.update(document); VersionedClass result = template.findById(id, VersionedClass.class); assertThat(result).satisfies(doc -> { - assertThat(doc.field).isNull(); - assertThat(doc.version).isEqualTo(2); + assertThat(doc.getField()).isNull(); + assertThat(doc.getVersion()).isEqualTo(2); }); template.delete(result); // cleanup } @@ -236,7 +237,7 @@ public void setsVersionEqualToNumberOfModifications() { Record raw = client.get(new Policy(), new Key(getNameSpace(), "versioned-set", id)); assertThat(raw.generation).isEqualTo(3); VersionedClass actual = template.findById(id, VersionedClass.class); - assertThat(actual.version).isEqualTo(3); + assertThat(actual.getVersion()).isEqualTo(3); template.delete(actual); // cleanup } @@ -252,7 +253,7 @@ public void onlyFirstUpdateSucceedsAndNextAttemptsShouldFailWithOptimisticLockin long counterValue = counter.incrementAndGet(); String data = "value-" + counterValue; try { - template.update(new VersionedClass(id, data, document.version)); + template.update(new VersionedClass(id, data, document.getVersion())); } catch (OptimisticLockingFailureException e) { optimisticLock.incrementAndGet(); } @@ -402,22 +403,53 @@ public void TestAddToMapSpecifyingMapFieldOnly() { public void updateAllShouldThrowExceptionOnUpdateForNonExistingKey() { // batch write operations are supported starting with Server version 6.0+ if (ServerVersionUtils.isBatchWriteSupported(client)) { - Person person1 = new Person(id, "svenfirstName", 11); - Person person2 = new Person(nextId(), "svenfirstName", 11); - Person person3 = new Person(nextId(), "svenfirstName", 11); - template.save(person3); + VersionedClass first = new VersionedClass("newId1", "foo"); // This class has a version field (class + // field annotated with @Version). The constructor does not receive the version, so it stays equal to zero + VersionedClass second = new VersionedClass("newId2", "bar"); // + assertThat(first.getVersion() == 0).isTrue(); // The document's version is zero meaning there is no + // corresponding DB record + assertThat(second.getVersion() == 0).isTrue(); + template.insert(first); + assertThat(first.getVersion() == 1).isTrue(); // The document's version is equal to one meaning there is + // a corresponding DB record // RecordExistsAction.UPDATE_ONLY - assertThatThrownBy(() -> template.updateAll(List.of(person1, person2))) - .isInstanceOf(AerospikeException.BatchRecordArray.class); + assertThatThrownBy(() -> template.updateAll(List.of(first, second))) // An attempt to update versioned + // documents without already existing DB records results in getting BatchRecordArray exception + .isInstanceOf(AerospikeException.BatchRecordArray.class) + .hasMessageContaining("Errors during batch update"); + assertThat(first.getVersion() == 2).isTrue(); // This document's version gets updated after it is read + // from the corresponding DB record + assertThat(second.getVersion() == 0).isTrue(); // This document's version stays equal to zero as there is + // no corresponding DB record + + assertThat(template.findById(first.getId(), VersionedClass.class)).isEqualTo(first); + assertThat(template.findById(second.getId(), VersionedClass.class)).isNull(); - assertThat(template.findById(person1.getId(), Person.class)).isNull(); - assertThat(template.findById(person2.getId(), Person.class)).isNull(); - assertThat(template.findById(person3.getId(), Person.class)).isEqualTo(person3); } } @Test public void updateAllIfDocumentsNotChanged() { + // batch write operations are supported starting with Server version 6.0+ + if (ServerVersionUtils.isBatchWriteSupported(client)) { + int age1 = 140335200; + int age2 = 177652800; + Person person1 = new Person(id, "Wolfgang M", age1); + Person person2 = new Person(nextId(), "Johann B", age2); + template.insertAll(List.of(person1, person2)); + template.updateAll(List.of(person1, person2)); + + Person result1 = template.findById(person1.getId(), Person.class); + Person result2 = template.findById(person2.getId(), Person.class); + assertThat(result1.getAge()).isEqualTo(age1); + assertThat(result2.getAge()).isEqualTo(age2); + template.delete(result1); // cleanup + template.delete(result2); // cleanup + } + } + + @Test + public void updateAllIfDocumentsChanged() { // batch write operations are supported starting with Server version 6.0+ if (ServerVersionUtils.isBatchWriteSupported(client)) { int age1 = 140335200; @@ -425,12 +457,17 @@ public void updateAllIfDocumentsNotChanged() { Person person1 = new Person(id, "Wolfgang", age1); Person person2 = new Person(nextId(), "Johann", age2); template.insertAll(List.of(person1, person2)); + + person1.setFirstName("Wolfgang M"); + person2.setFirstName("Johann B"); template.updateAll(List.of(person1, person2)); Person result1 = template.findById(person1.getId(), Person.class); Person result2 = template.findById(person2.getId(), Person.class); assertThat(result1.getAge()).isEqualTo(age1); + assertThat(result1.getFirstName()).isEqualTo("Wolfgang M"); assertThat(result2.getAge()).isEqualTo(age2); + assertThat(result2.getFirstName()).isEqualTo("Johann B"); template.delete(result1); // cleanup template.delete(result2); // cleanup } diff --git a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateDeleteRelatedTests.java b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateDeleteRelatedTests.java index fd6d9c43d..5a9b12613 100644 --- a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateDeleteRelatedTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateDeleteRelatedTests.java @@ -34,7 +34,7 @@ public void deleteByObject_ignoresDocumentVersionEvenIfDefaultGenerationPolicyIs try { VersionedClass initialDocument = new VersionedClass(id, "a"); reactiveTemplate.insert(initialDocument).block(); - reactiveTemplate.update(new VersionedClass(id, "b", initialDocument.version)).block(); + reactiveTemplate.update(new VersionedClass(id, "b", initialDocument.getVersion())).block(); Mono deleted = reactiveTemplate.delete(initialDocument).subscribeOn(Schedulers.parallel()); StepVerifier.create(deleted).expectNext(true).verifyComplete(); @@ -107,7 +107,8 @@ public void simpleDeleteByObjectWithSetName() { StepVerifier.create(deleted).expectNext(true).verifyComplete(); // then - Mono result = reactiveTemplate.findById(id, Person.class, OVERRIDE_SET_NAME).subscribeOn(Schedulers.parallel()); + Mono result = reactiveTemplate.findById(id, Person.class, OVERRIDE_SET_NAME) + .subscribeOn(Schedulers.parallel()); StepVerifier.create(result).expectComplete().verify(); } @@ -172,7 +173,7 @@ public void deleteAllWithSetName_ShouldDeleteAllDocuments() { reactiveTemplate.deleteByIds(ids, OVERRIDE_SET_NAME); List list = reactiveTemplate.findByIds(ids, - SampleClasses.DocumentWithExpiration.class, OVERRIDE_SET_NAME) + SampleClasses.DocumentWithExpiration.class, OVERRIDE_SET_NAME) .subscribeOn(Schedulers.parallel()).collectList().block(); assertThat(list).isEmpty(); } diff --git a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateSaveRelatedTests.java b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateSaveRelatedTests.java index fa4b3f94d..42b3b9bee 100644 --- a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateSaveRelatedTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateSaveRelatedTests.java @@ -36,8 +36,8 @@ public void save_shouldSaveAndSetVersion() { VersionedClass first = new VersionedClass(id, "foo"); reactiveTemplate.save(first).subscribeOn(Schedulers.parallel()).block(); - assertThat(first.version).isEqualTo(1); - assertThat(findById(id, VersionedClass.class).version).isEqualTo(1); + assertThat(first.getVersion()).isEqualTo(1); + assertThat(findById(id, VersionedClass.class).getVersion()).isEqualTo(1); } @Test @@ -45,8 +45,8 @@ public void saveWithSetName_shouldSaveAndSetVersion() { VersionedClass first = new VersionedClass(id, "foo"); reactiveTemplate.save(first, OVERRIDE_SET_NAME).subscribeOn(Schedulers.parallel()).block(); - assertThat(first.version).isEqualTo(1); - assertThat(findById(id, VersionedClass.class, OVERRIDE_SET_NAME).version).isEqualTo(1); + assertThat(first.getVersion()).isEqualTo(1); + assertThat(findById(id, VersionedClass.class, OVERRIDE_SET_NAME).getVersion()).isEqualTo(1); } @Test @@ -86,7 +86,8 @@ public void save_shouldUpdateNullField() { @Test public void saveWithSetName_shouldUpdateNullField() { VersionedClass versionedClass = new VersionedClass(id, null); - VersionedClass saved = reactiveTemplate.save(versionedClass, OVERRIDE_SET_NAME).subscribeOn(Schedulers.parallel()).block(); + VersionedClass saved = reactiveTemplate.save(versionedClass, OVERRIDE_SET_NAME) + .subscribeOn(Schedulers.parallel()).block(); reactiveTemplate.save(saved, OVERRIDE_SET_NAME).subscribeOn(Schedulers.parallel()).block(); } @@ -138,12 +139,12 @@ public void save_shouldUpdateExistingDocument() { VersionedClass one = new VersionedClass(id, "foo"); reactiveTemplate.save(one).subscribeOn(Schedulers.parallel()).block(); - reactiveTemplate.save(new VersionedClass(id, "foo1", one.version)) + reactiveTemplate.save(new VersionedClass(id, "foo1", one.getVersion())) .subscribeOn(Schedulers.parallel()).block(); VersionedClass value = findById(id, VersionedClass.class); - assertThat(value.version).isEqualTo(2); - assertThat(value.field).isEqualTo("foo1"); + assertThat(value.getVersion()).isEqualTo(2); + assertThat(value.getField()).isEqualTo("foo1"); } @Test @@ -153,7 +154,7 @@ public void save_shouldSetVersionWhenSavingTheSameDocument() { reactiveTemplate.save(one).subscribeOn(Schedulers.parallel()).block(); reactiveTemplate.save(one).subscribeOn(Schedulers.parallel()).block(); - assertThat(one.version).isEqualTo(3); + assertThat(one.getVersion()).isEqualTo(3); } @Test @@ -163,14 +164,14 @@ public void save_shouldUpdateAlreadyExistingDocument() { VersionedClass initial = new VersionedClass(id, "value-0"); reactiveTemplate.save(initial).subscribeOn(Schedulers.parallel()).block(); - assertThat(initial.version).isEqualTo(1); + assertThat(initial.getVersion()).isEqualTo(1); AsyncUtils.executeConcurrently(numberOfConcurrentSaves, () -> { boolean saved = false; while (!saved) { long counterValue = counter.incrementAndGet(); VersionedClass messageData = findById(id, VersionedClass.class); - messageData.field = "value-" + counterValue; + messageData.setField("value-" + counterValue); try { reactiveTemplate.save(messageData).subscribeOn(Schedulers.parallel()).block(); saved = true; @@ -181,9 +182,9 @@ public void save_shouldUpdateAlreadyExistingDocument() { VersionedClass actual = findById(id, VersionedClass.class); - assertThat(actual.field).isNotEqualTo(initial.field); - assertThat(actual.version).isNotEqualTo(initial.version) - .isEqualTo(initial.version + numberOfConcurrentSaves); + assertThat(actual.getField()).isNotEqualTo(initial.getField()); + assertThat(actual.getVersion()).isNotEqualTo(initial.getVersion()) + .isEqualTo(initial.getVersion() + numberOfConcurrentSaves); } @Test @@ -308,7 +309,8 @@ public void saveAllWithSetName_rejectsDuplicateId() { StepVerifier.create(reactiveTemplate.saveAll(List.of(first, first), OVERRIDE_SET_NAME)) .expectError(AerospikeException.BatchRecordArray.class) .verify(); - reactiveTemplate.delete(findById(id, VersionedClass.class, OVERRIDE_SET_NAME), OVERRIDE_SET_NAME).block(); // cleanup + reactiveTemplate.delete(findById(id, VersionedClass.class, OVERRIDE_SET_NAME), OVERRIDE_SET_NAME) + .block(); // cleanup } } } diff --git a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateUpdateTests.java b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateUpdateTests.java index 83ccfe298..0db151e87 100644 --- a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateUpdateTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateUpdateTests.java @@ -142,26 +142,26 @@ public void updateSpecificFieldsWithFieldAnnotatedPropertyActualValue() { public void updatesFieldValueAndDocumentVersion() { VersionedClass document = new VersionedClass(id, "foobar"); create(reactiveTemplate.insert(document)) - .assertNext(updated -> assertThat(updated.version).isEqualTo(1)) + .assertNext(updated -> assertThat(updated.getVersion()).isEqualTo(1)) .verifyComplete(); - assertThat(findById(id, VersionedClass.class).version).isEqualTo(1); + assertThat(findById(id, VersionedClass.class).getVersion()).isEqualTo(1); - document = new VersionedClass(id, "foobar1", document.version); + document = new VersionedClass(id, "foobar1", document.getVersion()); create(reactiveTemplate.update(document)) - .assertNext(updated -> assertThat(updated.version).isEqualTo(2)) + .assertNext(updated -> assertThat(updated.getVersion()).isEqualTo(2)) .verifyComplete(); assertThat(findById(id, VersionedClass.class)).satisfies(doc -> { - assertThat(doc.field).isEqualTo("foobar1"); - assertThat(doc.version).isEqualTo(2); + assertThat(doc.getField()).isEqualTo("foobar1"); + assertThat(doc.getVersion()).isEqualTo(2); }); - document = new VersionedClass(id, "foobar2", document.version); + document = new VersionedClass(id, "foobar2", document.getVersion()); create(reactiveTemplate.update(document)) - .assertNext(updated -> assertThat(updated.version).isEqualTo(3)) + .assertNext(updated -> assertThat(updated.getVersion()).isEqualTo(3)) .verifyComplete(); assertThat(findById(id, VersionedClass.class)).satisfies(doc -> { - assertThat(doc.field).isEqualTo("foobar2"); - assertThat(doc.version).isEqualTo(3); + assertThat(doc.getField()).isEqualTo("foobar2"); + assertThat(doc.getVersion()).isEqualTo(3); }); reactiveTemplate.delete(document).block(); // cleanup } @@ -170,22 +170,22 @@ public void updatesFieldValueAndDocumentVersion() { public void updateSpecificFieldsWithDocumentVersion() { VersionedClass document = new VersionedClass(id, "foobar"); reactiveTemplate.insert(document).block(); - assertThat(findById(id, VersionedClass.class).version).isEqualTo(1); + assertThat(findById(id, VersionedClass.class).getVersion()).isEqualTo(1); - document = new VersionedClass(id, "foobar1", document.version); + document = new VersionedClass(id, "foobar1", document.getVersion()); List fields = new ArrayList<>(); fields.add("field"); reactiveTemplate.update(document, fields).block(); assertThat(findById(id, VersionedClass.class)).satisfies(doc -> { - assertThat(doc.field).isEqualTo("foobar1"); - assertThat(doc.version).isEqualTo(2); + assertThat(doc.getField()).isEqualTo("foobar1"); + assertThat(doc.getVersion()).isEqualTo(2); }); - document = new VersionedClass(id, "foobar2", document.version); + document = new VersionedClass(id, "foobar2", document.getVersion()); reactiveTemplate.update(document, fields).block(); assertThat(findById(id, VersionedClass.class)).satisfies(doc -> { - assertThat(doc.field).isEqualTo("foobar2"); - assertThat(doc.version).isEqualTo(3); + assertThat(doc.getField()).isEqualTo("foobar2"); + assertThat(doc.getVersion()).isEqualTo(3); }); reactiveTemplate.delete(findById(id, VersionedClass.class)).block(); // cleanup } @@ -195,11 +195,11 @@ public void updatesFieldToNull() { VersionedClass document = new VersionedClass(id, "foobar"); reactiveTemplate.insert(document).block(); - document = new VersionedClass(id, null, document.version); + document = new VersionedClass(id, null, document.getVersion()); reactiveTemplate.update(document).block(); assertThat(findById(id, VersionedClass.class)).satisfies(doc -> { - assertThat(doc.field).isNull(); - assertThat(doc.version).isEqualTo(2); + assertThat(doc.getField()).isNull(); + assertThat(doc.getVersion()).isEqualTo(2); }); reactiveTemplate.delete(findById(id, VersionedClass.class)).block(); // cleanup @@ -216,7 +216,7 @@ public void setsVersionEqualToNumberOfModifications() { .assertNext(keyRecord -> assertThat(keyRecord.record.generation).isEqualTo(3)) .verifyComplete(); VersionedClass actual = findById(id, VersionedClass.class); - assertThat(actual.version).isEqualTo(3); + assertThat(actual.getVersion()).isEqualTo(3); reactiveTemplate.delete(actual).block(); // cleanup } @@ -231,7 +231,7 @@ public void setsVersionEqualToNumberOfModificationsWithSetName() { .assertNext(keyRecord -> assertThat(keyRecord.record.generation).isEqualTo(3)) .verifyComplete(); VersionedClass actual = findById(id, VersionedClass.class, OVERRIDE_SET_NAME); - assertThat(actual.version).isEqualTo(3); + assertThat(actual.getVersion()).isEqualTo(3); reactiveTemplate.delete(actual, OVERRIDE_SET_NAME).block(); // cleanup } @@ -247,7 +247,7 @@ public void onlyFirstUpdateSucceedsAndNextAttemptsShouldFailWithOptimisticLockin AsyncUtils.executeConcurrently(numberOfConcurrentSaves, () -> { long counterValue = counter.incrementAndGet(); String data = "value-" + counterValue; - reactiveTemplate.update(new VersionedClass(id, data, document.version)) + reactiveTemplate.update(new VersionedClass(id, data, document.getVersion())) .onErrorResume(OptimisticLockingFailureException.class, (e) -> { optimisticLock.incrementAndGet(); return Mono.empty(); diff --git a/src/test/java/org/springframework/data/aerospike/query/reactive/ReactiveIndexedPersonRepositoryQueryTests.java b/src/test/java/org/springframework/data/aerospike/query/reactive/ReactiveIndexedPersonRepositoryQueryTests.java index 585e17acb..36229f629 100644 --- a/src/test/java/org/springframework/data/aerospike/query/reactive/ReactiveIndexedPersonRepositoryQueryTests.java +++ b/src/test/java/org/springframework/data/aerospike/query/reactive/ReactiveIndexedPersonRepositoryQueryTests.java @@ -338,7 +338,7 @@ public void findByMapKeyValueBetween() { @Test public void findPersonsByMetadata() { - // creating a condition "since_update_time metadata value is less than 50 seconds" + // creating an expression "since_update_time metadata value is less than 50 seconds" Qualifier sinceUpdateTimeLt10Seconds = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.LT) @@ -347,7 +347,7 @@ public void findPersonsByMetadata() { assertThat(reactiveRepository.findUsingQuery(new Query(sinceUpdateTimeLt10Seconds)).collectList().block()) .containsAll(allIndexedPersons); - // creating a condition "since_update_time metadata value is between 1 millisecond and 50 seconds" + // creating an expression "since_update_time metadata value is between 1 millisecond and 50 seconds" Qualifier sinceUpdateTimeBetween1And50000 = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.BETWEEN) @@ -360,17 +360,17 @@ public void findPersonsByMetadata() { } @Test - public void findPersonsByQualifiers() { + public void findPersonsByQuery() { Iterable result; - // creating a condition "since_update_time metadata value is greater than 1 millisecond" + // creating an expression "since_update_time metadata value is greater than 1 millisecond" Qualifier sinceUpdateTimeGt1 = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.GT) .setValue1AsObj(1L) .build(); - // creating a condition "since_update_time metadata value is less than 50 seconds" + // creating an expression "since_update_time metadata value is less than 50 seconds" Qualifier sinceUpdateTimeLt50Seconds = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.LT) @@ -379,7 +379,7 @@ public void findPersonsByQualifiers() { assertThat(reactiveRepository.findUsingQuery(new Query(sinceUpdateTimeLt50Seconds)).collectList().block()) .containsAll(allIndexedPersons); - // creating a condition "since_update_time metadata value is between 1 and 50 seconds" + // creating an expression "since_update_time metadata value is between 1 and 50 seconds" Qualifier sinceUpdateTimeBetween1And50000 = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.BETWEEN) @@ -387,14 +387,14 @@ public void findPersonsByQualifiers() { .setValue2AsObj(50000L) .build(); - // creating a condition "firsName is equal to Petra" + // creating an expression "firsName is equal to Petra" Qualifier firstNameEqPetra = Qualifier.builder() .setField("firstName") .setFilterOperation(FilterOperation.EQ) .setValue1(Value.get("Petra")) .build(); - // creating a condition "age is equal to 34" + // creating an expression "age is equal to 34" Qualifier ageEq34 = Qualifier.builder() .setField("age") .setFilterOperation(FilterOperation.EQ) @@ -403,7 +403,7 @@ public void findPersonsByQualifiers() { result = reactiveRepository.findUsingQuery(new Query(ageEq34)).collectList().block(); assertThat(result).containsOnly(petra); - // creating a condition "age is greater than 34" + // creating an expression "age is greater than 34" Qualifier ageGt34 = Qualifier.builder() .setFilterOperation(FilterOperation.GT) .setField("age") diff --git a/src/test/java/org/springframework/data/aerospike/repository/PersonRepositoryQueryTests.java b/src/test/java/org/springframework/data/aerospike/repository/PersonRepositoryQueryTests.java index b7f76dd72..c93f90f78 100644 --- a/src/test/java/org/springframework/data/aerospike/repository/PersonRepositoryQueryTests.java +++ b/src/test/java/org/springframework/data/aerospike/repository/PersonRepositoryQueryTests.java @@ -1193,7 +1193,7 @@ void findPersonById() { @Test void findPersonsByIds() { - List persons = repository.findById(List.of(dave.getId(), carter.getId())); + List persons = (List) repository.findAllById(List.of(dave.getId(), carter.getId())); assertThat(persons).containsOnly(dave, carter); } @@ -1295,15 +1295,15 @@ void findPersonsByEmail() { @Test void findPersonsByMetadata() { - // creating a condition "since_update_time metadata value is less than 50 seconds" - Qualifier sinceUpdateTimeLt10Seconds = Qualifier.metadataBuilder() + // creating an expression "since_update_time metadata value is less than 50 seconds" + Qualifier sinceUpdateTimeLt50Seconds = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.LT) .setValue1AsObj(50000L) .build(); - assertThat(repository.findUsingQuery(new Query(sinceUpdateTimeLt10Seconds))).containsAll(allPersons); + assertThat(repository.findUsingQuery(new Query(sinceUpdateTimeLt50Seconds))).containsAll(allPersons); - // creating a condition "since_update_time metadata value is between 1 millisecond and 50 seconds" + // creating an expression "since_update_time metadata value is between 1 millisecond and 50 seconds" Qualifier sinceUpdateTimeBetween1And50000 = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.BETWEEN) @@ -1311,21 +1311,21 @@ void findPersonsByMetadata() { .setValue2AsObj(50000L) .build(); assertThat(repository.findUsingQuery(new Query(sinceUpdateTimeBetween1And50000))) - .containsAll(repository.findUsingQuery(new Query(sinceUpdateTimeLt10Seconds))); + .containsAll(repository.findUsingQuery(new Query(sinceUpdateTimeLt50Seconds))); } @Test void findPersonsByQuery() { Iterable result; - // creating a condition "since_update_time metadata value is greater than 1 millisecond" + // creating an expression "since_update_time metadata value is greater than 1 millisecond" Qualifier sinceUpdateTimeGt1 = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.GT) .setValue1AsObj(1L) .build(); - // creating a condition "since_update_time metadata value is less than 50 seconds" + // creating an expression "since_update_time metadata value is less than 50 seconds" Qualifier sinceUpdateTimeLt50Seconds = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.LT) @@ -1333,7 +1333,7 @@ void findPersonsByQuery() { .build(); assertThat(repository.findUsingQuery(new Query(sinceUpdateTimeLt50Seconds))).containsAll(allPersons); - // creating a condition "since_update_time metadata value is between 1 millisecond and 50 seconds" + // creating an expression "since_update_time metadata value is between 1 millisecond and 50 seconds" Qualifier sinceUpdateTimeBetween1And50000 = Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.BETWEEN) @@ -1341,14 +1341,14 @@ void findPersonsByQuery() { .setValue2AsObj(50000L) .build(); - // creating a condition "firstName is equal to Carter" + // creating an expression "firstName is equal to Carter" Qualifier firstNameEqCarter = Qualifier.builder() .setField("firstName") .setFilterOperation(FilterOperation.EQ) .setValue1(Value.get("Carter")) .build(); - // creating a condition "age is equal to 49" + // creating an expression "age is equal to 49" Qualifier ageEq49 = Qualifier.builder() .setField("age") .setFilterOperation(FilterOperation.EQ) @@ -1357,7 +1357,7 @@ void findPersonsByQuery() { result = repository.findUsingQuery(new Query(ageEq49)); assertThat(result).containsOnly(carter); - // creating a condition "firstName is equal to Leroi" with sorting by age and limiting by 1 row + // creating an expression "firstName is equal to Leroi" with sorting by age and limiting by 1 row Qualifier firstNameEqLeroi = Qualifier.builder() .setField("firstName") .setFilterOperation(FilterOperation.EQ) @@ -1369,7 +1369,7 @@ void findPersonsByQuery() { result = repository.findUsingQuery(query); assertThat(result).containsOnly(leroi2); - // creating a condition "age is greater than 49" + // creating an expression "age is greater than 49" Qualifier ageGt49 = Qualifier.builder() .setFilterOperation(FilterOperation.GT) .setField("age") @@ -1378,24 +1378,24 @@ void findPersonsByQuery() { result = repository.findUsingQuery(new Query(ageGt49)); assertThat(result).doesNotContain(carter); - // creating a condition "id equals Carter's id" + // creating an expression "id equals Carter's id" Qualifier keyEqCartersId = Qualifier.idEquals(carter.getId()); result = repository.findUsingQuery(new Query(keyEqCartersId)); assertThat(result).containsOnly(carter); - // creating a condition "id equals Boyd's id" + // creating an expression "id equals Boyd's id" Qualifier keyEqBoydsId = Qualifier.idEquals(boyd.getId()); result = repository.findUsingQuery(new Query(keyEqBoydsId)); assertThat(result).containsOnly(boyd); // analogous to {@link SimpleAerospikeRepository#findAllById(Iterable)} - // creating a condition "id equals Carter's id OR Boyd's id" + // creating an expression "id equals Carter's id OR Boyd's id" Qualifier keyEqMultipleIds = Qualifier.idIn(carter.getId(), boyd.getId()); result = repository.findUsingQuery(new Query(keyEqMultipleIds)); assertThat(result).containsOnly(carter, boyd); // metadata and id qualifiers combined with AND - // not more than one id qualifier is allowed, otherwise the conditions will not overlap because of uniqueness + // not more than one id qualifier is allowed, otherwise the expressions will not overlap because of uniqueness result = repository.findUsingQuery(new Query(Qualifier.and(sinceUpdateTimeGt1, keyEqCartersId))); // if a query contains id qualifier the results are firstly narrowed down to satisfy the given id(s) // that's why queries with qualifier like Qualifier.or(Qualifier.idEquals(...), ageGt49)) return empty result @@ -1449,7 +1449,7 @@ void findPersonsByQuery() { } @Test - void findPersonsByQualifiersMustBeValid() { + void findPersonsByQueryMustBeValid() { assertThatThrownBy(() -> repository.findUsingQuery(new Query(Qualifier.metadataBuilder() .setMetadataField(SINCE_UPDATE_TIME) .setFilterOperation(FilterOperation.BETWEEN) @@ -1790,8 +1790,6 @@ void countByLastName_forExistingResult() { assertThatThrownBy(() -> repository.countByLastName("Leroi")) .isInstanceOf(UnsupportedOperationException.class) .hasMessage("Query method Person.countByLastName is not supported"); - -// assertThat(result).isEqualTo(2); } @Test diff --git a/src/test/java/org/springframework/data/aerospike/sample/PersonRepository.java b/src/test/java/org/springframework/data/aerospike/sample/PersonRepository.java index df4096a3a..6285e13ff 100644 --- a/src/test/java/org/springframework/data/aerospike/sample/PersonRepository.java +++ b/src/test/java/org/springframework/data/aerospike/sample/PersonRepository.java @@ -64,13 +64,6 @@ public interface PersonRepository

extends AerospikeRepository< // Dynamic Projection List findByFirstNameAndLastName(String firstName, String lastName, Class type); - /** - * Find all entities that have primary key in the given list. - * - * @param ids List of primary keys - */ - List

findById(List ids); - /** * Find all entities that satisfy the condition "have primary key in the given list and first name equal to the * specified string". diff --git a/src/test/java/org/springframework/data/aerospike/sample/SampleClasses.java b/src/test/java/org/springframework/data/aerospike/sample/SampleClasses.java index 2ea3b3042..21f73fe34 100644 --- a/src/test/java/org/springframework/data/aerospike/sample/SampleClasses.java +++ b/src/test/java/org/springframework/data/aerospike/sample/SampleClasses.java @@ -556,12 +556,12 @@ private Person(Set

addresses) { public static class VersionedClass { @Version - public Long version; // do not change to primitive type. See #72 issue - public String field; + private long version; + private String field; @Id private String id; - public VersionedClass(String id, String field, Long version) { + public VersionedClass(String id, String field, long version) { this.id = id; this.field = field; this.version = version; @@ -574,14 +574,15 @@ public VersionedClass(String id, String field) { } } - @Getter + @Data + @Document public static class VersionedClassWithAllArgsConstructor { - public final String field; + private String field; @Id - private final String id; + private String id; @Version - public long version; + private long version; @PersistenceCreator public VersionedClassWithAllArgsConstructor(String id, String field, long version) { @@ -892,7 +893,7 @@ public static class DocumentWithBigIntegerAndNestedArray { public static class ObjectWithIntegerArray { @Version - public Long version; + private Long version; Integer[] array; public ObjectWithIntegerArray(Integer[] array) {