spring-data-mongodb
spring-data-mongodb copied to clipboard
Repository query keyword IS_EMPTY not supported
The documentation for repository query keywords (link) mentions support for the IsEmpty keyword, however, it fails with "Unsupported keyword" when used.
Steps to reproduce 0) spring initializr:
- Maven & Kotlin on Java 17
- Spring Boot 3.2.1
- Dependencies: MongoDB Reactive
- Inside file with
@SpringBootApplication, add the code below - Start the app (no need for a running Mongo instance to get the exception)
interface CustomRepository : ReactiveMongoRepository<CustomData, String> {
fun findByIdIsEmpty(id: String): Mono<Boolean>
}
data class CustomData(val id: String)
@Component
class Demo(val customRepository: CustomRepository) {
@Bean
fun accessRepo() {
customRepository.findByIdIsEmpty("non-existent").block()
}
}
Result
Error creating bean 'accessRepo', caused by org.springframework.beans.BeanInstantiationException: Failed to instantiate [void]: Factory method 'accessRepo' threw exception with message: Unsupported keyword
The exception is thrown inside org.springframework.data.mongodb.repository.query.from (line number 254), because the switch-statement above (line 168) has no case for IS_EMPTY, even though the keyword is defined in org.springframework.data.repository.query.parser.Type.
True, the documentation is misleading as the repository sections lists the generic overview from data-commons which holds the entire list of supported keywords.
Supporting IS_EMPTY would be an enhancement and we'd have to define it's behaviour given the various scenarios the MongoDB data model allows.
I could imagine using an $eq comparision to build the support. Like { field : { $eq : "" } } would be sufficient for simple String. Collections could be checked with { field: { $size: 0 } } and objects with { field : { $eq : {} } }. Numeric values, should error, though one might argue a stored null may be considered empty, but what about primitive types then. Generic types in the java domain model may also be tricky and we'd need to consider @Field(targetType=...) to pick the right format.