Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Spring data extending default methods
@NoRepositoryBean
interface BaseGenericReactiveMongoRepository<T> : ReactiveMongoRepository<T, String> {
fun patch(id: String, fields: Map<String, Any>): Mono<T>
}
interface BookRepository : ReactiveMongoRepository<Book, String> {
findByNameContainingIgnoreCaseAndVisibileIsTrue(name:String): Flux<Book>
}
@Configuration
@EnableReactiveMongoRepositories(
basePackages = ["**.repository"],
repositoryBaseClass = SimpleBaseGenericReactiveMongoRepository::class
)
class MongoConfiguration
class SimpleBaseGenericReactiveMongoRepository<ENTITY>(
private val entityInformation: MappingMongoEntityInformation<ENTITY, String>,
private val template: ReactiveMongoTemplate
) : SimpleReactiveMongoRepository<ENTITY, String>(entityInformation, template),
BaseGenericReactiveMongoRepository<ENTITY> {
private val eventPublisher: ApplicationEventPublisher?
init {
val context = template.converter.mappingContext as MongoMappingContext
val indexCreator = MongoPersistentEntityIndexCreator(context) { collectionName ->
IndexOperationsAdapter.blocking(template.indexOps(collectionName))
}
eventPublisher = MongoMappingEventPublisher(indexCreator)
}
override fun patch(id: String, fields: Map<String, Any>): Mono<ENTITY> {
val collection = entityInformation.collectionName
val query = Query(Criteria.where("_id").`is`(id))
val document = Document()
return findById(id)
.flatMap { entity ->
maybeEmitEvent(BeforeConvertEvent<ENTITY>(entity, collection))
document.putAll(fields)
val update = Update()
fields
.filter { entry ->
!hashSetOf("_id", "createdAt", "createdBy", "modifiedAt", "modifiedBy").contains(entry.key)
}
.forEach { entry -> update.set(entry.key, entry.value) }
maybeEmitEvent(BeforeSaveEvent<ENTITY>(entity, document, collection))
template.updateFirst(query, update, collection)
}
.then(findById(id)).map { entity ->
maybeEmitEvent(AfterSaveEvent<ENTITY>(entity, document, collection))
entity
}
}
private fun <T> maybeEmitEvent(event: MongoMappingEvent<T>) {
eventPublisher?.publishEvent(event)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment