开发者

Conversation scope unexpected behavior

开发者 https://www.devze.com 2023-03-31 08:12 出处:网络
I have a JSF page where users can enter their car into my database. The form has three input fields: Manufacturer

I have a JSF page where users can enter their car into my database. The form has three input fields:

  • Manufacturer
  • Model
  • Registration

The Manufacturer and Model field are both autocompletion fields. In order to complete the Model field, I need to know what value the user selected in the Manufacturer field prior to submitting the form. To that end, I set up an AJAX call to inform the managed bean of the selected value:

<p:autoComplete id="manufacturer"
                minQueryLength="3"
                completeMethod="#{carController.complete}"
                forceSelection="true">
   <p:ajax event="itemSelect"
           listener="#{carController.manufacturerSelected}" />
</p:autoComplete>

And in the managed bean:

public void manufacturerSelected(SelectEvent se) {
    manufacturer = se.getObject().toString();
}

The autocomplete field and handler method for the model look about the same, with slighly different values.

To retain the manufacturer value across the multiple XHR requests, I have set the bean to ConversationScoped and begin the conversation in a @PostConstruct annotated method:

@Named
@ConversationScoped
public class CarController implements Serializable {

@Inject
private Conversation conversation;

@PostConstruct
private void init() {
    conversation.begin();
}

What I would expect is the bean getting only instantiated once for the page because the conversation has not been ended yet, and retaining the value in the manufacturer field. This, however, does not hold true, and the bean is instantiated again for each XHR request, causing the manufacturer field to be null as well. Setting a breakpoint in the PostConstruct method revealed that it is in fact getting called and so is the manufacturerSelected method.

I suspect this has something to do with the fact that I am not ma开发者_如何学编程nually propagating the conversation ID but the documentation says that this ID should automatically be propagated with any faces request. Is this in fact true, and, does that mean that XHR requests are not necessarily faces requests?

Edit: Setting breakpoints at various locations in the bean has revealed that each XHR request has a new bean (conversation.getId() keeps changing) so I am obviously not propagating the ID right. How would one propagate the ID with p:ajax and where can I get it with EL?


Since you're not really using a conversation (at least not in the example you give), why not use the view scope? This will do exactly what you want, without the overhead of having to propogate a conversation id.

Do note that for @ViewScoped to work, you have to change the bean to a JSF managed bean (remove @Named). This is due to a design bug/spec oversight in Java EE 6. If you want to keep using CDI, then there's a Java EE 6 extension from Seam 3 available that fixes this bug.


Yup. This is an issue with JSF 2 and Primefaces together not propagating the conversation id. You can try the below workaround. (This is for other who will end up here due to the same issue).

<p:autoComplete id="manufacturer"
            minQueryLength="3"
            completeMethod="#{carController.complete}"
            forceSelection="true" onchange="updateManufacturer([{name:'cid',value:'#{javax.enterprise.context.conversation.id}'}])">
</p:autoComplete>
<p:remoteCommand name="updateManufacturer" action="#{carController.manufacturerSelected}"
                                 process="manufacturer" />
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号