reembedAll

Re-embed every proposition by writing a fresh vector onto each node. Lighter than the interface default (which re-saves the whole view): it SETs only embedding, leaving mentions and other properties untouched.

IT RECONCILES ITS OWN INDEX. A same-shape re-embed needs no DDL, and used to be the only case this handled — the index was left to the host, which had to know that only one order works. A change of embedding model makes the stored vectors disagree with the index whether the new model is wider or narrower, so the shape is checked here and the index remade around the rewrite when it has moved.

ONE BAD PROPOSITION DOES NOT SINK THE RUN. Each proposition is embedded on its own, and the vectors are written in batches of REEMBED_WRITE_BATCH, each batch committed atomically by Drivine's own transaction. A proposition whose embed fails keeps its node; if its old vector no longer matches the index width it is cleared, so the index never describes a vector of the wrong shape and the proposition is simply absent from vector search until retried. When anything failed, PropositionReembedIncompleteException is thrown AFTER the index is back, naming the failed ids. Re-running this is the retry: every write is an idempotent SET.

NOT @Transactional, and that is the point of this method's shape.

Neo4j will not take schema work and data work in one transaction. Doing the index DDL inside the transactional rewrite deadlocked: the DDL runs on its own session and waits on the schema locks the open data transaction holds, while that transaction waits to commit. The request never returned, and the graph was left with the index dropped and the vectors not yet rewritten — observed on a live appliance, a transaction Running for ten minutes with no current query.

So the DDL sits on either side of the writes rather than inside a transaction with them. Between the drop and the remake there is a window in which proposition search finds nothing; that is inherent to changing the shape of an index and is why the caller is told the index was recreated. The remake happens whether the rewrite succeeded or threw.

NOT_SUPPORTED, not a bare absence of the annotation: this CLASS carries @Transactional, so saying nothing here still runs the whole method in a transaction and reproduces the deadlock. It also suspends a transaction a CALLER already opened, which is the same hazard arriving from outside — save overrides the class default for its own reasons and is the precedent.

Throws

when some propositions could not be embedded; all others were written and the index is restored