If you want that level of safety, then yes, you’re out of luck with the current versions of Hibernate Search. It’s simply not what it was designed for. We generally assume that this level of failure requires full reindexing. From experience on non-distributed applications, it wasn’t a problem; it will probably be on large-scale distributed applications.
Regarding sync, be aware that you’ll never get complete, immediate consistency between the database and the index. The best we can hope for is eventual consistency: after X seconds, database changes are mirrored in the index. Some people use automatic indexing for most of their data, but exclude some associations because it would slow down their application too much. They launch a full reindexing periodically, and accept that the index may be out of sync in the meantime. What level of consistency you can accept is, obviously, specific to your own requirements.
Regarding Kafka, there are multiple solutions to ensuring no events are lost:
- The transactional outbox pattern you mentioned.
- Some kind of two-phase commit, though I doubt it’s available/efficient with Kafka.
- Some custom, simpler two-phase commit: send the events to a Kafka queue with the explicit instruction that they should not be processed before X seconds, where X is a number of seconds beyond which you’re reasonably certain the commit will have been performed. Rollbacks don’t matter in this case: we’d just reindex unnecessarily.
- Change Data Capture, e.g. with Debezium: we’d source the events from the database’s transaction log instead of sourcing them from Hibernate ORM like we currently do.
Which solution we’ll pick exactly is not determined yet. If you’re interested in shaping out a prototype, we can definitely talk about it here or on our chat.