I'm facing this right now, and the best solution I can see is to use
triggers in the database itself. Rather than trying to determine which
fields have changed (especially when some may be multi-megabyte BLOB
fields), I'm going to have shadow tables that have all the fields of the
original tables, plus modification information.
Disk space is cheap.