A tamed animal whose owner has no known name is stored with a null owner, and restoring it throws a NullPointerException at the owner step, which drops the rest of the restore. A null owner name is now skipped like an empty one.
The consumer ran Material.matchMaterial's two regex passes on names they cannot change, and re-encoded the same blockdata strings into ids on every row. Plain enum names now go straight to getMaterial, and stringToByteData caches its results per string, bounded, reset when the id maps reload and skipped on ClickHouse.
The id allocators read the counter, add one and store it without a lock, so two threads that see new names at the same time (region threads on Folia, lookup and API threads everywhere) can give the same id to two different names. Allocation now holds the ConfigHandler monitor reloadAndGetId already uses, with a re-check, and queues the insert after releasing it.
Every dispense copied the dispenser's block entity twice on the region thread (block.getState() in the dispense listeners and inventory.getHolder() in onInventoryInteract), and both copies were only used for their type, location and live inventory. Paper can hand out non-snapshot states for this, so the dispense path now asks for those through a new PaperInterface.getBlockState(Block, boolean), falling back to a normal snapshot on Spigot.