How to avoid BusyConversationException in jsf
Asked Answered
I

4

15

I'm getting BusyConversationException while navigating through pages in my jsf project. This mostly happens if the user tries to navigate to another page during an ajax call. This also happens when the user clicks on a link right after clicking on another link without waiting for loading of the page.

For example if the user clicks on more than one link which are generated through a code similar to below one we definitely get this exception. Another example is, lets say the user enter a query on a text field, and our application make an ajax call for searching this query. During that query if the user click on some button to navigate to another page BusyConversationException occurs too.

<h:commandLink value="#{theProfile.profileName}"
               title="#{theProfile.profileName}"
               action="#{profileBean.aProfileSelected}">
               <f:setPropertyActionListener target="#{currentProfileWebBean.theProfile}" value="#{theProfile}"/>
</h:commandLink>

I can catch this type of exception in an ExceptionHandler class which extends ExceptionHandlerWrapper class but I can't save my current state and the best I can do for this case is to redirect to main page when this exception occurs.

Is there any solution for avoiding this? Thanks in advance for answers and comments.

Iota answered 3/12, 2012 at 10:38 Comment(3)
Note: BusyConversationException is not part of JSF. I added the CDI tag.Antidromic
Are there multiple Conversation.begin calls happening?Bentinck
I'm having this problem, too, if it's any reassurance, and I'm surprised by how few people seem to be having it (based on a web search). I may wind up eliminating my conversation-scoped beans and using session-scoped and view-scoped (with the CDI view scope provided by Seam Faces).Wollastonite
M
2

As mentioned in the other answers, this happens if an ajax request is still being processed or if an ajax event is triggered prior to the actual click on the submitting commandLink or commandButton (for instance by a change event on an input field).

Therfore it is not possible to avoid BusyConversationExceptions with onclick="preventEventPropagation(event)";, since the AJAX events are not triggered via propagation.

The issue can easily be avoided by listening for running ajax requests and blocking submits until the pending ajax events have been completed.

The issue and solution are explained in more detail in this blog post JSF2 AJAX/Submit conversation issue.

Mayweed answered 4/3, 2015 at 8:46 Comment(0)
W
0

i found this,

Indicates that the container has rejected a request because a concurrent request is associated with the same conversation context.

The container ensures that a long-running conversation may be associated with at most one request at a time, by blocking or rejecting concurrent requests. If the container rejects a request, it must associate the request with a new transient conversation and throw an exception of type BusyConversationException from the restore view phase of the JSF lifecycle.

refer here

Whittle answered 22/4, 2013 at 4:29 Comment(0)
T
-1

I've been seeing this occasionally too. I'm starting to think it's a good idea to put some effort into serializing access to conversations:

  1. Avoid propagating the conversation ID (cid) when you don't need that conversation instance for the target view. Specifically, unrelated navigation links/buttons should suppress the cid parameter (haven't thought about exactly how to do that)
  2. When starting a request that uses an active conversation, disable other UI elements that propagate the conversation and could therefore cause concurrent access. The PrimeFaces or (even better) PrimeFaces Extensions blockUI components work well as a translucent overlay, along with a PrimeFaces p:ajaxStatus to show the busy status.
  3. Begin conversations as late as possible. This will minimize the cases where a long-running conversation would be propagated.

I don't think that any of this is a complete solution, though. As soon as the cid ends up in the location bar (which happens when you do a non-ajax post back of a form when a conversation is active), you potentially lose control over the timing of access to that conversation due to multiple tabs/windows, bookmarks, etc.

Thimble answered 4/12, 2012 at 22:55 Comment(3)
With our case we are having trouble when to end the conversation and start a new one. How can I start a new conversation whenever the user click on a h:commandLink (the example code I gave in the example)? I tried to end the conversation in the backing bean through the setter#{currentProfileWebBean.theProfile} , but I see that the cid is not changing at all, and postConstructs are not called again? So I guess conversation is not ending properly, do you have any idea about it?Iota
This is where you'd want to suppress the cid from being submitted from the h:commandLink (which again I haven't thought through how to accomplish, and may require use of h:link instead of h:commandLink). That way, there won't be an active conversation for the request and you are free to begin a new one. The technique can be thought of as leaving a conversation rather than putting an end to it.Thimble
Thats exactly what I like to learn, using h:commandLink to post some parameters, but not to post cid so that a new conversation can be start in the new page. If I use h:link then I need to pass some parameters (for this example I need to pass "theProfile" object as a parameter) in the url link which I don't like to do so.Iota
S
-1

I also faced the same problem, when I used to click the .

I have read in one of the book, busyConevrsation happens with that event two actions are happening, so they said use : onclick="preventEventPropagation(event)"; in commandLink to prevent the event propagation for that click. So I have used the same and it's working for me.

So now am not getting the BusyConversationException :)

Sandstorm answered 6/1, 2015 at 9:29 Comment(1)
the preventEventPropogration doesn't help here, this would only work if there was another on click listener being triggered. However in this case either an AJAX request has already been triggered and is still being processed or is triggered prior to the processing of the actual click for instance by an ajax change event. To avoid such issues you have to listen for pending ajax requests and postpone the submit until the request has finished processing. I have linked a blog post in my own answer which explains the issue and a possible solution in more detail.Mayweed

© 2022 - 2024 — McMap. All rights reserved.