Support for the Unique Key for a Collection
Adding Unique Key Constraints in Azure CosmosDB is supported now https://docs.microsoft.com/en-us/azure/cosmos-db/unique-keys
When will this be supported by the spring-data-cosmosdb?
@mbhaskar Could you please help to share some information about this ?
The unique key policy should be supported similar to how @DocumentIndexingPolicy works, by supplying an annotation on the document class.
Thanks a lot, that should be something for serivce side configuration. We will add it to our feature list.
As a workaround while waiting for first class support of this feature, I have come up with the following (in Kotlin):
Spring Bean Configuration Hooking
@Configuration
class CosmosUniqueKeyPolicyConfig(val documentDbConfiguration: AbstractDocumentDbConfiguration) {
@Bean
@Primary
fun uniqueKeyPolicyHookingDocumentClient(): DocumentClient =
uniqueKeyPolicyHookingDocumentDbFactory().getDocumentClient()
@Bean
@Primary
fun uniqueKeyPolicyHookingDocumentDbFactory(): DocumentDbFactory =
UniqueKeyPolicyHookingDocumentDbFactory(documentDbConfiguration.config)
@Bean
@Primary
fun uniqueKeyPolicyHookingDocumentDbTemplate(): DocumentDbTemplate =
DocumentDbTemplate(
this.uniqueKeyPolicyHookingDocumentDbFactory(),
documentDbConfiguration.mappingDocumentDbConverter(),
documentDbConfiguration.config.database)
}
class UniqueKeyPolicyHookingDocumentClient(
serviceEndpoint: String?,
masterKey: String?,
connectionPolicy: ConnectionPolicy?,
desiredConsistencyLevel: ConsistencyLevel?
) : DocumentClient(serviceEndpoint, masterKey, connectionPolicy, desiredConsistencyLevel) {
override fun createCollection(databaseLink: String?, collection: DocumentCollection?, options: RequestOptions?): ResourceResponse<DocumentCollection> {
// Insert a unique key policy to the datamodel collection
if (collection?.id == DocumentCollectionNames.datamodel) {
collection.uniqueKeyPolicy = DataModel.uniqueKeyPolicy
}
return super.createCollection(databaseLink, collection, options)
}
}
class UniqueKeyPolicyHookingDocumentDbFactory(config: DocumentDBConfig) : DocumentDbFactory(config) {
override fun getDocumentClient(): DocumentClient {
val config = config
val policy = config.connectionPolicy
val userAgent = "MyServer" + ";" + policy.userAgentSuffix
policy.userAgentSuffix = userAgent
return UniqueKeyPolicyHookingDocumentClient(config.uri, config.key, policy, config.consistencyLevel)
}
}
object DocumentCollectionNames {
const val datamodel = "datamodel_collection"
}
@Document(collection = DocumentCollectionNames.datamodel, ru = "400")
data class DataModel(
@Id
@GeneratedValue
val id: String?,
@PartitionKey
val partitionKey: String,
val uniqueKeyWithinPartition: String
) {
companion object {
val uniqueKeyPolicy: UniqueKeyPolicy by lazy {
UniqueKeyPolicy().apply {
uniqueKeys = listOf(UniqueKey().apply { paths = listOf("/uniqueKeyWithinPartition") })
}
}
}
}
@allenhumphreys Thanks for the suggestions.
@jainro - I will propose this feature for our next semester.
Is there any progress here? I don't see anything in azure-spring-data-cosmos:3.5.0 and the workaround provided here is not adequate anymore