9

In JSF 2.0, the most obvious use-case for the view scope is a single page with potentially multiple AJAX post-backs. Using CDI instead of JSF managed beans leaves us without the view scope so we're either left to implement our own, use a (possibly bug-ridden) third party implementation or use the conversation scope.

My question: Is the conversation scope a worthy substitute for the view scope in the typical AJAX situation? Like the view scope, does it allow multiple instances per session? What are the pitfalls?

I'm aware of one of the pitfalls, namely that the conversation scope isn't automatically deleted when the user navigates away from the page, but instead is deleted after a time-out. But I'm not sure what happens when the user navigates back to that page before the conversation has timed out.

UPDATE

The conversation scope does indeed support multiple instances per session. This book states as much and I was able to confirm this using code from ch. 2.

Distortum
  • 6,740
  • 9
  • 58
  • 103

1 Answers1

4

In any @ConversationScoped CDI beans, you must have the following field:

@Inject
private Conversation conversation; 

Whenever you want to begin the conversation, you need to check if the bean is in transient state. Otherwise, IllegalStateException will be thrown. It would be something like this:

public void beginConversation() {
  if (conversation.isTransient()) conversation.begin();
}

By doing this, your bean will be in the long-running state. Hence, if the user navigate aways from the page and navigates back later on, you can always check if his conversation has timed-out or not and bring him to the page where he left.

Besides, I have been using @ViewScoped ManagedBean together with CDI bean for a while. You can still use @Inject to inject a CDI bean into a MangedBean. I don't think you can do the other way around though. Anyway, I have no idea if this would cause anything bad to happen later. However, up until now, I have never met any issues. If you really want to use @ViewScoped, I think you can try :P.

UPDATE:

Is the conversation scope a worthy substitute for the view scope in the typical AJAX situation?

I don't think @ConversationScoped can ever fully replace @ViewScoped.

Like the view scope, does it allow multiple instances per session?

No, you cannot have multiple instances per session. As I mentioned, if you start a new Conversation while the old conversation is still in long-running state, you will get IllegalStateException.

What are the pitfalls?

Well, one of the main advantages of @ViewScoped over @RequestScoped is that you don't need to re-initiate data every time the user submits the form to the same View. However, with @ConversationScoped, this advantage is over-used. While this problem is not as serious as if you use @SessionScoped, you still need to hold the initiated data as long as the @ConversationScoped bean lives. The longer the conversation, the more data you may need to hold.

Mr.J4mes
  • 8,680
  • 8
  • 42
  • 79
  • Can you inject EJBs into managed beans, though? If so, doesn't that mean there's virtually no reason to used CDI to manage JSF scopes? That doesn't sound right... – Distortum Jan 01 '12 at 14:05
  • If you want to inject EJB into managed bean, you can simply use `@EJB`. This would work on both `CDI beans` and `ManagedBean`. Besides, the reason to use `CDI` is NOT about managing JSF scopes. It's more about the fact that you can inject a larger number of things into CDI beans. – Mr.J4mes Jan 01 '12 at 14:17
  • "Besides, the reason to use CDI is NOT about managing JSF scopes." Yeah, I get that. It will manage JSF scopes in a way that's more integrated with the rest of the app server. I'm not going to accept the answer because I'm holding out for an answer that directly addresses this use case of conversation scopes. But thanks for being informative. +1 because the answer is at least useful. – Distortum Jan 01 '12 at 15:38
  • 1
    "No, you cannot have multiple instances per session." [This book](http://horstmann.com/corejsf/) must be wrong on page 54. Among other things, it states a conversation is tied to a browser tab/window. I might just run some tests to see what's what. – Distortum Jan 01 '12 at 17:31
  • 2
    Tested and confirmed that multiple instances of the same conversation scope declaration can exist in the same session. So at this stage, it's looking like the conversation scope is at least a viable alternative to the view scope. But there's still the issue of how to avoid the pitfalls of using it in this scenario. I will investigate further, meanwhile seeing what others post about this. – Distortum Jan 01 '12 at 18:02
  • @SteveTaylor: did you try calling `conversation.begin();` again before calling `conversation.end();`? – Mr.J4mes Jan 01 '12 at 19:06
  • Yes yes, that would surely throw an `IllegalStateException`, but that's missing the point. And why would anyone do that anyway? Obviously what's happening in my test is that multiple instances of the same `@ConversationScoped` bean class are being instantiated, each servicing a different browser window yet tied to the same session. In that respect, it has the same behaviour as `@ViewScoped`. – Distortum Jan 01 '12 at 19:29
  • @SteveTaylor are you sure you had multiple instances? I think what you had should be the same instance of `@ConversationScoped` bean for multiple browser windows. – Mr.J4mes Jan 02 '12 at 04:07
  • Yes, I'm sure. What else can I say? My test confirmed it. Try it for yourself. If you have the Core JavaServer Faces (3rd ed.) book, it's in chapter 2. – Distortum Jan 02 '12 at 13:08
  • It seems that you should correct "No, you cannot have multiple instances per session." – John Donn Aug 10 '16 at 13:59