diff --git a/README.adoc b/README.adoc index c9697be28..ac43e1f12 100644 --- a/README.adoc +++ b/README.adoc @@ -56,6 +56,8 @@ Data Aerospike - Projections] [width="100%",cols="<24%,<14%,<18%,<26%,<18%",options="header",] |=== |Spring Data Aerospike |Spring Boot |Aerospike Client |Aerospike Reactor Client |Aerospike Server +|4.8.x |3.3.x |7.2.x |7.1.x |5.2.x.x + + |4.7.x |3.2.x |7.2.x |7.1.x |5.2.x.x + |4.6.x |3.2.x |7.2.x |7.1.x |5.2.x.x + diff --git a/pom.xml b/pom.xml index d527d9dc5..dfe4eb4ec 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.aerospike spring-data-aerospike - 4.7.1 + 4.8.0 Spring Data Aerospike Aerospike Inc. @@ -16,7 +16,7 @@ org.springframework.data.build spring-data-parent - 3.2.4 + 3.3.0 @@ -24,23 +24,23 @@ ${java.version} ${java.version} UTF-8 - 3.2.4 - 3.2.4 - 3.2.3 - 3.2.3 - 4.1.1 + 3.3.0 + 3.3.0 + 3.3.0 + 3.3.0 + 4.1.2 3.3.0 1.6 7.2.1 7.1.0 3.6.1 - 3.1.5 + 3.1.6 2.12.7 - 1.18.30 + 1.18.32 4.2.1 - 1.5.3 + 1.5.6 8.0.1.Final - 4.1.107.Final + 4.1.110.Final diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index f9dfeecf9..4fdd4e915 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.7.1 +:revnumber: 4.8.0 :revdate: {localdate} :toc: :toc-placement!: diff --git a/src/main/asciidoc/reference/configuration.adoc b/src/main/asciidoc/reference/configuration.adoc index 18be5b007..00e29bcb0 100644 --- a/src/main/asciidoc/reference/configuration.adoc +++ b/src/main/asciidoc/reference/configuration.adoc @@ -177,7 +177,6 @@ It has precedence over reading from application.properties. Here is an example: @EnableAerospikeRepositories(basePackageClasses = TestRepository.class) class ApplicationConfig extends AbstractAerospikeDataConfiguration { - @Override public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) { aerospikeDataSettings.setScansEnabled(false); @@ -210,7 +209,6 @@ It has precedence over reading from application.properties. Here is an example: @EnableAerospikeRepositories(basePackageClasses = TestRepository.class) class ApplicationConfig extends AbstractAerospikeDataConfiguration { - @Override public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) { aerospikeDataSettings.setCreateIndexesOnStartup(true); @@ -240,7 +238,6 @@ It has precedence over reading from application.properties. Here is an example: @EnableAerospikeRepositories(basePackageClasses = TestRepository.class) class ApplicationConfig extends AbstractAerospikeDataConfiguration { - @Override public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) { aerospikeDataSettings.setIndexCacheRefreshSeconds(3600); @@ -270,7 +267,6 @@ It has precedence over reading from application.properties. Here is an example: @EnableAerospikeRepositories(basePackageClasses = TestRepository.class) class ApplicationConfig extends AbstractAerospikeDataConfiguration { - @Override public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) { aerospikeDataSettings.setServerVersionRefreshSeconds(3600); @@ -300,7 +296,6 @@ It has precedence over reading from application.properties. Here is an example: @EnableAerospikeRepositories(basePackageClasses = TestRepository.class) class ApplicationConfig extends AbstractAerospikeDataConfiguration { - @Override public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) { aerospikeDataSettings.setQueryMaxRecords(10000L); @@ -330,7 +325,6 @@ It has precedence over reading from application.properties. Here is an example: @EnableAerospikeRepositories(basePackageClasses = TestRepository.class) class ApplicationConfig extends AbstractAerospikeDataConfiguration { - @Override public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) { aerospikeDataSettings.setBatchWriteSize(100); @@ -386,7 +380,6 @@ It has precedence over reading from application.properties. Here is an example: @EnableAerospikeRepositories(basePackageClasses = TestRepository.class) class ApplicationConfig extends AbstractAerospikeDataConfiguration { - @Override public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) { aerospikeDataSettings.setKeepOriginalKeyTypes(false); @@ -396,3 +389,35 @@ class ApplicationConfig extends AbstractAerospikeDataConfiguration { *Default*: `false` (store keys only as `String`). +[[configuration.write-sorted-maps]] +=== writeSortedMaps + +[source,properties] +---- +# application.properties +spring-data-aerospike.data.writeSortedMaps=true +---- + +Define how Maps and POJOs are written: `true` - as sorted maps (`TreeMap`, default), `false` - as unsorted (`HashMap`). + +Writing as unsorted maps (`false`) degrades performance of Map-related operations and does not allow comparing Maps, +so it is strongly recommended to change the default value only if required during upgrade from older versions +of Spring Data Aerospike. + +NOTE: Another way of defining the parameter is overriding the `configureDataSettings()` method. +It has precedence over reading from application.properties. Here is an example: + +[source,java] +---- +// overriding method +@EnableAerospikeRepositories(basePackageClasses = TestRepository.class) +class ApplicationConfig extends AbstractAerospikeDataConfiguration { + + @Override + public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) { + aerospikeDataSettings.setWriteSortedMaps(true); + } +} +---- + +*Default*: `true` (write Maps and POJOs as sorted maps). diff --git a/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java b/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java index 921700037..1ea4c8f1b 100644 --- a/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java +++ b/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java @@ -59,14 +59,14 @@ public QueryEngine queryEngine(IAerospikeClient aerospikeClient, QueryEngine queryEngine = new QueryEngine(aerospikeClient, statementBuilder, filterExpressionsBuilder, settings.getDataSettings()); boolean scansEnabled = settings.getDataSettings().isScansEnabled(); - log.debug("AerospikeDataSettings.scansEnabled: {}", scansEnabled); + log.info("AerospikeDataSettings.scansEnabled: {}", scansEnabled); queryEngine.setScansEnabled(scansEnabled); long queryMaxRecords = settings.getDataSettings().getQueryMaxRecords(); - log.debug("AerospikeDataSettings.queryMaxRecords: {}", queryMaxRecords); + log.info("AerospikeDataSettings.queryMaxRecords: {}", queryMaxRecords); queryEngine.setQueryMaxRecords(queryMaxRecords); if (!settings.getDataSettings().isWriteSortedMaps()) { log.info("AerospikeDataSettings.writeSortedMaps is set to false, " + - "Maps and POJOs will be written as unsorted Maps (degrades performance of Map-related operations ," + + "Maps and POJOs will be written as unsorted Maps (degrades performance of Map-related operations," + " does not allow comparing Maps)"); } return queryEngine; @@ -78,7 +78,7 @@ public AerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCre AerospikeIndexResolver aerospikeIndexResolver, ObjectProvider template, AerospikeSettings settings) { boolean indexesOnStartup = settings.getDataSettings().isCreateIndexesOnStartup(); - log.debug("AerospikeDataSettings.indexesOnStartup: {}", indexesOnStartup); + log.info("AerospikeDataSettings.indexesOnStartup: {}", indexesOnStartup); return new AerospikePersistenceEntityIndexCreator(aerospikeMappingContext, indexesOnStartup, aerospikeIndexResolver, template); } @@ -91,7 +91,7 @@ public IndexRefresher indexRefresher(IAerospikeClient aerospikeClient, IndexesCa refresher.refreshIndexes(); int refreshFrequency = settings.getDataSettings().getIndexCacheRefreshSeconds(); processCacheRefreshFrequency(refreshFrequency, refresher); - log.debug("AerospikeDataSettings.indexCacheRefreshSeconds: {}", refreshFrequency); + log.info("AerospikeDataSettings.indexCacheRefreshSeconds: {}", refreshFrequency); return refresher; } diff --git a/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java b/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java index 7477dfdf2..c5e1ac7af 100644 --- a/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java +++ b/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java @@ -71,10 +71,15 @@ public ReactorQueryEngine reactorQueryEngine(IAerospikeReactorClient aerospikeRe filterExpressionsBuilder, settings.getDataSettings()); boolean scansEnabled = settings.getDataSettings().isScansEnabled(); queryEngine.setScansEnabled(scansEnabled); - log.debug("AerospikeDataSettings.scansEnabled: {}", scansEnabled); + log.info("AerospikeDataSettings.scansEnabled: {}", scansEnabled); long queryMaxRecords = settings.getDataSettings().getQueryMaxRecords(); - log.debug("AerospikeDataSettings.queryMaxRecords: {}", queryMaxRecords); + log.info("AerospikeDataSettings.queryMaxRecords: {}", queryMaxRecords); queryEngine.setQueryMaxRecords(queryMaxRecords); + if (!settings.getDataSettings().isWriteSortedMaps()) { + log.info("AerospikeDataSettings.writeSortedMaps is set to false, " + + "Maps and POJOs will be written as unsorted Maps (degrades performance of Map-related operations," + + " does not allow comparing Maps)"); + } return queryEngine; } @@ -110,7 +115,7 @@ public ReactiveAerospikePersistenceEntityIndexCreator aerospikePersistenceEntity AerospikeIndexResolver aerospikeIndexResolver, ObjectProvider template, AerospikeSettings settings) { boolean indexesOnStartup = settings.getDataSettings().isCreateIndexesOnStartup(); - log.debug("AerospikeDataSettings.indexesOnStartup: {}", indexesOnStartup); + log.info("AerospikeDataSettings.indexesOnStartup: {}", indexesOnStartup); return new ReactiveAerospikePersistenceEntityIndexCreator(aerospikeMappingContext, indexesOnStartup, aerospikeIndexResolver, template); } 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 b13d70b39..638c59dc3 100644 --- a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java +++ b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java @@ -37,6 +37,8 @@ public class AerospikeDataSettings { // Define how @Id fields (primary keys) and Map keys are stored: false - always as String, // true - preserve original type if supported boolean keepOriginalKeyTypes = false; - // Define how Maps are written: true - as TreeMaps (default), false - as HashMaps + // Define how Maps and POJOs are written: true - as sorted maps (TreeMaps, default), false - as unsorted (HashMaps) + // Writing unsorted maps (false) degrades performance of Map-related operations and does not allow comparing Maps, + // strongly recommended not to use except during upgrade from older versions of Spring Data Aerospike (if required) boolean writeSortedMaps = true; } diff --git a/src/main/java/org/springframework/data/aerospike/repository/query/CriteriaDefinition.java b/src/main/java/org/springframework/data/aerospike/repository/query/CriteriaDefinition.java index 03c1a66a5..480402e45 100644 --- a/src/main/java/org/springframework/data/aerospike/repository/query/CriteriaDefinition.java +++ b/src/main/java/org/springframework/data/aerospike/repository/query/CriteriaDefinition.java @@ -45,11 +45,29 @@ enum AerospikeNullQueryCriterion { } enum AerospikeMetadata { - SINCE_UPDATE_TIME, // Exp.sinceUpdate(), milliseconds - LAST_UPDATE_TIME, // Exp.lastUpdate(), nanoseconds since epoch - VOID_TIME, // Exp.voidTime(), nanoseconds since epoch - TTL, // Exp.ttl(), integer seconds - RECORD_SIZE_ON_DISK, // Exp.deviceSize(), bytes - RECORD_SIZE_IN_MEMORY // Exp.memorySize(), bytes + /** + * Exp.sinceUpdate(), milliseconds + */ + SINCE_UPDATE_TIME, + /** + * Exp.lastUpdate(), nanoseconds since epoch + */ + LAST_UPDATE_TIME, + /** + * Exp.voidTime(), nanoseconds since epoch + */ + VOID_TIME, + /** + * Exp.ttl(), integer seconds + */ + TTL, + /** + * Exp.recordSize() (Exp.deviceSize() for Server ver. < 7.0), bytes + */ + RECORD_SIZE_ON_DISK, + /** + * Exp.recordSize() (Exp.memorySize() for Server ver. < 7.0), bytes + */ + RECORD_SIZE_IN_MEMORY } }