One of the hardest bit's of Seam is know which SCOPE to use when
The documentation mentions in several places that SESSION scope is frowned upon and/or used sparingly. Yet, nearly all the examples use it, especially those dealing with the DataModel.
It's saying you should only use to hold data that is actually session scoped e.g. a logged in User. There are lots of ways to use a DataModel not in the session - page parameters, el enhancement, PAGE scope. But of course. if you want to remember search results when the user returns to the search page at some later point, then you need the SESSION scope.
I can see how its not scalable to keep a large data model in memory for the duration of a user's session, but it seems equally non-scalable to query the database each time the user interacts with the page it supports.
Both can be considered bad practice. You should only fetch the data you actually need; if your resultset is large you should scroll/page over the resultset, and lazy-fetch the data. This is where converstations come in.
Advantages are that you can subsets of the data to display in different windows. This is not possible with session scope as the subsets would overwrite each other. Cleaning up conversations is much easier than clearing out the session.
However sometimes you do want to shared data between browsers/tabs - the session scope is needed here.
I've experimented with long running conversations, etc, but then I have to make sure I end the conversation somehow when the user navigates away from the page.
It's quite acceptable to just leave a conversation hanging and let it time out if the user navigates away from the page in some indeterminate fashion (e.g. not hitting the cancel button)
I guess before I get myself too contorted trying to figure out the best way to do something, I thought I'd ask about when to use which SCOPE. When do you use SESSION and when do you use CONVERSATION?
Only use SESSION scope for data that belongs in the session; rarely would you put an action bean in SESSION scope. You can store the id of the entity in SESSION scope, and manage it using a CONVERSATION scoped Home/manager object thus preventing LazyInitializationExceptions. See SeamEntityHomeForLongRunningContexts
What about long running or temporary conversations?
Well Seam creates temporary conversations for each request for you - they aren't something you need to worry about. You certainly want to use long running conversations - atomic conversations (where you explicitly flush the persistence context) are great!
If I use long running conversations, how to handle the user jumping to another page via a link or bookmark?
For navigation links I would either end the conversation (without flushing the persistence context) or not propagate the conversation (depending on how/whether I want to provide workspace management).
With bookmarks the choice is made for you - the current conversation is not propagated. And it's likely the conversation that was active when the bookmark was made is now not active (timeout or explicit end) - so be aware of this (no-conversation-view-id is useful here)!
If you have a page with a table for example that supports paging, what scope should I use?
This does depend on whether you use ajax for paging. Assuming you aren't, then the PAGE scope works here, as does CONVERSATION scope. Take a look at how the Seam Application Framework deals with this (see the reference manual/seam-gen for this).