Advanced Apache Cayenne
(practical demonstration)
by Andrus Adamchik, ObjectStyle LLC
CMS:Admin app
Tapestry stack
Admin App
(demo)
Admin App - Takeaway
• We can reuse Cayenne and service code between the apps
• When editing objects, ObjectContext is placed in the page scope
and should be reset when we start editing a new object
• Scope in Tapestry is managed with @Persist annotation
Lifecycle Events
(demo)
Lifecycle Events - Takeway
• Two ways to receive events - callbacks and listeners
• Use callbacks on persistent objects for simple things like
initialization
• Use listeners for more complex workflows, cross-entity
workflows
• Check out DataChannelFilter (will be discussed later)
Caching
Types of Cache
• What is cached?
• Object cache - objects cached by ID
• Query cache - lists cached by generated cache key
Types of Cache
• Where is it cached?
• Local cache - attached to an ObjectContext
• Shared cache - attached to a DataDomain (a common parent
of all ObjectContexts)
Object Cache
(very much like EOF)
• Stores objects (or DataRows) by ObjectId
• Prevents unneeded DB trips when navigating object graph
• Ensures uniquing
• Can be auto-synchronized across contexts orVMs
• Memory leak-free (shared - LRU; local - weak refs)
Query Cache
(nothing like EOF)
• Stores lists of objects (or lists of DataRows) by query key
• Prevents unneeded DB trips when running queries
• Fully “managed” - time-based or event-based expiration policies
• Lightweight synchronization via cache groups (inVM, cross-VM)
• Scales much better
Query Cache
(demo)
Caching and Performance
Turn off Cross-Context
Synchronization
• Good for desktop apps, terrible for webapps
• unrelated contexts receiving events they don’t care about
• Clustering of object cache doesn’t perform well
• Without clustering, behavior differs for contexts in sameVM vs
differentVM
• Object auto-sync will interfere with optimistic locking
Turn off Cross-Context
Synchronization
binder.bindMap(Constants.PROPERTIES_MAP).put(Constants.SERVER_CONTEXTS_SYNC_PROPERTY, "false");
Use Query Cache
• Design your app with cache groups in mind
• Implement refresh based on expiration policies
• Implement refresh based on events and CacheInvalidationFilter
• Cluster refresh events. Clustering is lightweight, not prone to
breaking on code version changes
Consider Optimistic Locking
Caching and Performance
• Don’t try to sync individual objects
• Turn off cross-context synchronization
• Use query cache. Cluster it.
• Use optimistic locking
Q&A
Andrus Adamchik
andrus@objectstyle.com
twitter.com/andrus_a

Advanced Apache Cayenne