Switch instance methods to static methods where possible. Reduce method visibility in CassandraMappingContext and CassandraSimpleTypeHolder.
Reorder methods in MappingCassandraConverter. Remove unused CassandraPersistentProperty.isIndexed/getOwner methods and PropertyToFieldNameConverter type.
Remove CassandraPersistentEntity.getApplicationContext() and inject application context to BasicCassandraPersistentProperty from CassandraMappingContext.
CassandraPersistentProperty can now map only to a single column. Previously, CassandraPersistentProperty covered composite primary key mapping which required the mapping context in BasicCassandraPersistentProperty to resolve composite primary key entities. Composite primary keys are now resolved upfront without the need of indirection through CassandraPersistentProperty.
Remove CassandraMappingContext interface and replace it with BasicCassandraMappingContext. CassandraPersistentEntity is no longer required to declare MutablePersistentEntity but it's sufficient to implement PersistentEntity. Fall back to MappingContext instead of CassandraMappingContext use where just MappingContext is required.
Reintroduce BasicCassandraMappingContext extending from CassandraMappingContext to reduce breaking changes and ease migration.
* Resolve cycle between o.s.d.c.cql.core and o.s.d.c.cql.support via CassandraAccessor.
* Resolve cycle between o.s.d.c.cql.core.support and o.s.d.c.cql.support via CQLExceptionTranslator.
* Resolve cycle between o.s.d.c.cql.config and o.s.d.c.cql.core.keyspace via KeyspaceAttributes/DataCenterReplication.
We now follow a more consistent naming scheme for cassandra repository interfaces.
* The basic, store-specific interface is now named CassandraRepository
* An extended variant, using MapId's is named MapIdCassandraRepository
That results in the following renames:
* CassandraRepository -> MapIdCassandraRepository
* TypedIdCassandraRepository -> CassandraRepository
TypedIdCassandraRepository was re-introduced as deprecated variant now extending CassandraRepository to preserve a majority of existing repository declarations.
Adopt to API change from Publisher.subscribe() to Publisher.toProcessor(). Adopt to changed reactor-test groupId. Provide mocks for calls that allowed previously null Publishers.
We now insert the entire object including null values again in Cassandra using the repository save method. Objects that are saved through the repository are expected to be returned the same when retrieved again.
Cassandra entities don't have any indicator whether these entities are new to optimize null value handling and prevent tombstones in Cassandra. CassandraRepository exposes insert(…) to insert objects without inserting null values.
Previously, we attempted to execute insert/update conditionally on the entity structure which ended up issuing update statements containing all null values. Entities were not created and save(…) failed silently.
We relocated packages of the former Spring CQL module and mapping/convert packages of the Spring Data Cassandra module:
org.springframework.cassandra -> org.springframework.data.cql
org.springframework.cassandra.core.cql.generator -> org.springframework.data.cql.core.generator
org.springframework.cassandra.core.cql -> org.springframework.data.cql.core
org.springframework.data.cassandra.convert -> org.springframework.data.cassandra.core.convert
org.springframework.data.cassandra.mapping -> org.springframework.data.cassandra.core.mapping
We now support fluent query creation for Cassandra queries via Query. Query predicates are built with Criteria and Query that also take QueryOptions, Sort and limiting. Query accepts a column specification to specify column inclusion/exclusion along with function specification (TTL, WRITETIME).
Query query = Query.query(Criteria.where("userId").in("heisenberg", "mike")).and(Criteria.where("age").gt("51"));
query = query.columns(Columns.from("userId", "age").include("firstname"))
.with(new Sort("age"))
.with(QueryOptions.builder().fetchSize(10).build())
.withAllowFiltering()
.limit(10);
List<Person> people = operations.select(query, Person.class);
Query can be used with select, stream, update and delete Template API methods.
We now support fluent update creation via Update to specify individual update actions for a selection of rows.
Update supports the common Cassandra update assignments for singular, collection and map-typed columns and can increment/decrement counter columns.
Update update = Update.update("lastname", "White")
.addTo("firearms").appendAll("Ruger LCR", "M60")
.remove("propertiesSet", "trust")
.clear("friends");
Query query = Query.query(Criteria.where("id").is("heisenberg"));
template.update(query, update, Person.class);
Update can be used with the update Template API methods.
Encapsulate fields in BasicCassandraMappingContext, BasicCassandraPersistentEntity, BasicCassandraPersistentProperty, and refactor to immutable fields where possible.
We now only cache verified entities (by CassandraPersistentEntityMetadataVerifier) after adding PersistingEntities to the mapping context.
Previously invalid entities were included in the cache and calls to methods using caching returned invalid entities that were cached but not part of the mapping context.
Id types for entities are no longer required to implement Serializable. This requirement originates from ancient ORM patterns and had never a technical requirements for Cassandra. Id types are required to map either directly or convert to a Cassandra-supported data type.
Removal of deprecated and obsolete types and members. Listeners became obsolete by providing AsynCqlTemplate/AsyncCassandraTemplate as async operations return futures that allow synchronization. Other types are not used anymore.
Strict mode is no longer used. Switching to a lenient verification can be achieved with a custom verifier. Made VerifierMappingExceptions immutable by removing VerifierMappingExceptions.add(…).
Introduce CassandraCustomConversions extending o.s.d.convert.CustomConversions.
Remove o.s.d.cassandra.convert.CustomConversions implementation and utility classes, extend CassandraCustomConversions. Replace references to o.s.d.c.c.CustomConversions with o.s.d.convert.CustomConversions. Adapt tests and MappingCassandraConverter to CassandraCustomConversions.
Related ticket: DATACMNS-1035.
Replace Flux/Mono.onErrorResumeWith(…) with Flux/Mono.onErrorMap(…) and turn translateException into a method returning a mapping function instead of a Mono emitting the mapped exception.
We now test compatibility with Apache Cassandra's duration type (introduced with Apache Cassandra 3.10). Duration requires a driver version >= 3.2.0 so we drop build profiles against earlier driver versions and use Apache Cassandra 3.10 for integration tests.
Enforce frozen user types in collection types when creating tables and frozen user types when referencing a user type from another type. Previously, the driver returned frozen user-types and no interaction from our side was required. Move user-type specifics to UserTypeUtil.
Introduce compatibility code within the tests to build against different driver versions.