This is a common problem. What you need to do is force session serialization. This can be done by doing the following:
- Create a Phase Listener
- At the end of each phase, store a random attribute on to the session map
- e.g. sessionMap.put("CURRENT_TIME", System.currentTimeMillis())
- This will cause the modified data to be serialized to the datastore
The reason you need to do something like this is because, when the view tree was constructed, it was added to the session ... and then your business logic made changes to the components in the view tree, but unfortunately the changes made to these variable do not raise any events that inform GAE to serialize again. Which is why you would see ViewExpiredExceptions or data not being stored, etc.
This concept is similar in nature to the markDirty() concept that you might have come across with other view technologies.