First off, I really like this article! I wonder if there is a hybrid approach that has the benefits of both solutions but lacks some of the drawbacks of each.
Database assigned IDs either break object equality or has performance hits associated with pre-assigning IDs for each instance.
Application generated IDs make using the database from other applications (direct queries, other data feeds, etc) non-intuitive and in some cases very difficult if not impossible. Also, there are performance issues with using text for primary keys.
Couldn't AbstractPersistentObject have a uuid and an id member (uuid would not be stored in the database, but assigned for each object during initialization)? Then, in the equals and hashcode, first try to check equality with the id and default to the uuid if the id doesn't exist.
This way, initialization will be fast, object equality will be maintained, the database will remain usable and performance will not suffer.