One additional column info parameter is used, extract, which is called as a method on the inserted object with the column name as the only argument. The return value from this callback will be used to populate the column.

If the column extractor is omitted then the column will contain a copy of the entry data key by the same name, if it is a plain scalar. Otherwise the column will be NULL.

These columns are only used for lookup purposes, only data is consulted when loading entries.

For reasons of performance and ease of use database vendors ship with read committed transaction isolation by default.

This means that read locks are not acquired when data is fetched from the database, allowing it to be updated by another writer. If the current transaction then updates the value it will be silently overwritten.

IMHO this is a much bigger problem when the data is unstructured. This is because data is loaded and fetched in potentially smaller chunks, increasing the risk of phantom reads.

Unfortunately enabling truly isolated transaction semantics means that txn_commit may fail due to a lock contention, forcing you to repeat your transaction. Arguably this is more correct "read comitted", which can lead to race conditions.

Enabling repeatable read or serializable transaction isolation prevents transactions from interfering with eachother, by ensuring all data reads are performed with a shared lock.

If true (the defaults), will cause all select statement to be issued with a FOR UPDATE modifier on MySQL, Postgres and Oracle.

This is highly reccomended because these database provide low isolation guarantees as configured out the box, and highly interlinked graph databases are much more susceptible to corruption because of lack of transcational isolation than normalized relational databases.

You are problably using MySQL, which comes with a helpful data compression feature: when your serialized objects are larger than the maximum size of a BLOB column MySQL will simply shorten it for you.

Why BLOB defaults to 64k, and how on earth someone would consider silent data truncation a sane default I could never fathom, but nevertheless MySQL does allow you to disable this by setting the "strict" SQL mode in the configuration.

To resolve the actual problem (though this obviously won't repair your lost data), alter the entries table so that the data column uses the nonstandard LONGBLOB datatype.