Conversation versus Session Context
jrosskopf Feb 16, 2007 2:32 AMHello everybody,
I´m a little bit confused about using the conversation context in a backing bean.
I have the following facelet code:
<ui:define name="body">
<h:messages globalOnly="true" styleClass="message" />
<h:form id="panel" >
<h:panelGrid columns="1">
<h:panelGroup>
<h:selectOneMenu valueChangeListener="#{selectItemFacade.handleItemTypeChange}" onchange="submit()">
<f:selectItems value="#{selectItemFacade.availableItemTypes}" />
</h:selectOneMenu>
</h:panelGroup>
<h:panelGroup>
<h:panelGrid binding="#{selectItemFacade.selectedItemPreview}" />
</h:panelGroup>
<h:panelGroup>
<h:commandButton id="edit_button" action="#{selectItemFacade.edit}" />
</h:panelGroup>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
As you can see, some components are generated based on the selection made in the selectOneMenu. That works fine.
@Stateful
@Scope(ScopeType.CONVERSATION)
@Name("selectItemFacade")
public class SelectItemFacadeBean implements SelectItemFacade {
@Logger
Log log;
// Bijection
@Out()
ItemDescription selectedItemType;
@Out(required=false)
Item item;
// Instance
HtmlPanelGrid selectedItemPreview;
@Create
public void init() {
this.selectedItemPreview = (HtmlPanelGrid)FacesContext.getCurrentInstance().getApplication().createComponent(HtmlPanelGrid.COMPONENT_TYPE);
this.selectedItemType = ItemRegistry.INSTANCE.getDefaultItemDescription();
updateSelectedItemComponents();
}
private void updateSelectedItemComponents() {
if (this.selectedItemType != null && this.selectedItemPreview != null) {
selectedItemType.getPreviewComponent(FacesContext.getCurrentInstance(), this.selectedItemPreview, this.item);
}
}
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
public SelectItem[] getAvailableItemTypes() {
return ItemRegistry.INSTANCE.getAvailableTypesAsSelectItem();
}
public ItemDescription getSelectedItemType() {
return selectedItemType;
}
public void setSelectedItemType(ItemDescription selectedItemType) {
this.selectedItemType = selectedItemType;
}
public HtmlPanelGrid getSelectedItemPreview() {
return selectedItemPreview;
}
public void setSelectedItemPreview(HtmlPanelGrid selectedItemPreview) {
this.selectedItemPreview = selectedItemPreview;
}
// Actions
public void handleItemTypeChange(ValueChangeEvent evt) {
ItemDescription desc = ItemRegistry.INSTANCE.getDescription((String)evt.getNewValue());
if (desc != null) {
this.selectedItemType = desc;
updateSelectedItemComponents();
log.debug("Item type changed to " + this.selectedItemType.getLabel());
}
}
public String edit() {
log.debug("Action: edit called;");
if (this.selectedItemType != null && this.item == null) {
log.debug("Creating " + selectedItemType.getLabel() + " and getting edit Component;");
this.item = selectedItemType.createItemInstance();
//selectedItemType.getEditComponent(FacesContext.getCurrentInstance(), this.selectedItemEditor, this.item, "createItemFacade.item.tags");
}
return NavCodes.ACTION_EDIT;
}
@Destroy @Remove
public void destroy() { }
}
In the selectItemFacade component I want to outject the selectedItemType and the item to the session context, as the instances are needed for editing in another component.
Futher I thougth outjecting selectedItemPreview isn´t needed as the instance is private to the stateful session bean.
If I enter select.xhtml everything works fine for the moment. But if I click on the edit_button the page is redirected to the seam debug page and in the logfile there is the following error:
08:26:51,406 ERROR [SeamExceptionFilter] uncaught exception
javax.servlet.ServletException: /item/select.xhtml @23,71 binding="#{selectItemFacade.selectedItemPreview}": Target Unreachable, identifier 'selectItemFacade' resolved to null
Why is the instance in the stateful session bean now null.
Can somebody explain me, what I´m doing wrong? I already placed a @Begin annotation on the edit() method. No effect.
Thank you in advance.
Regards
---
Joachim