Inject private Conversation conversation always null
lightguard Jan 18, 2010 9:42 AMI'm not sure if this is a bug, or if I'm doing something I shouldn't be doing :) The code is below, but what's happening is the conversation is started via an Observer in one bean, then the conversation is used by a different observer (same event) on a different bean. The second bean is @ConversationScoped, the first is @ApplicationScoped. The conversation scoped bean never has a conversation that's non-null injected into it, very, very odd.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="title">Simple Greeting</ui:define>
<ui:define name="head">Simple Greeting</ui:define>
<ui:define name="content">
<h:form id="greetme">
<p><h:outputLabel value="Enter your name: " for="name"/>
<h:inputText id="name" value="#{printer.name}"/></p>
<p><h:commandButton value="Say Hello" action="#{printer.createSalutation}"><f:ajax render="@form" execute="@form" /></h:commandButton></p>
<p><h:outputText value="printer.salutation = #{printer.salutation}"/> </p>
<p><h:outputText value="printer.old_salutation = #{printer.old_salutation}"/> </p>
<p><h:outputText value="myConversationStatus.conversationSattus = #{myConversationStatus.conversationSattus}"/> </p>
<p><h:outputText value="my_application_scope_bean.my_application_scope_counter = #{my_application_scope_bean.my_application_scope_counter}"/> </p>
<p><h:outputText value="my_conversation_scope_bean.my_conversation_scope_counter = #{my_conversation_scope_bean.my_conversation_scope_counter}"/> </p>
<p><h:outputText value="Prime number #{printer.primeNumber} is hit!" rendered="#{printer.primeNumber != 0}"/></p>
</h:form>
</ui:define>
</ui:composition>
</html>The call to the Say Hello button starts things off.
@Named
@ConversationScoped
public class Printer implements Serializable
{
@Inject @Informal
GreetingInterface greeting;
@Inject
Conversation conversation;
@Inject
MyConversationStatus cstatus;
@Inject Event<SalutationEvent> createSalutationEvent;
private String name;
private String salutation = "nothing yet!";
private String old_salutation = "nothing yet!";
private int primeNumber;
public void startConversation()
{
cstatus.setConversationSattus("on");
}
public void endConversation()
{
cstatus.setConversationSattus("off");
conversation.end();
}
public void createSalutation()
{
this.primeNumber = 0;
this.createSalutationEvent.fire(new SalutationEvent());
this.old_salutation = salutation;
this.salutation = greeting.greet(name);
}
public String getSalutation()
{
return salutation;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
/**
* @return the old_salutation
*/
public String getOld_salutation()
{
return old_salutation;
}
/**
* @param old_salutation the old_salutation to set
*/
public void setOld_salutation(String old_salutation)
{
this.old_salutation = old_salutation;
}
public void primeEventObserver(@Observes @Prime Integer pPrimeNumber)
{
this.primeNumber = pPrimeNumber;
}
public int getPrimeNumber()
{
return this.primeNumber;
}
}In this class the conversation is never null, I can start up the conversation just fine, there aren't any issues.
@ApplicationScoped
@Named("my_application_scope_bean")
public class MyApplicationScopeBean
{
private int my_application_scope_counter;
@Inject
Conversation conversation;
@Inject @Prime
Event<Integer> primeEvent;
@Inject
MyConversationStatus convStatus;
public int getMy_application_scope_counter()
{
return this.my_application_scope_counter;
}
public void setMy_application_scope_counter(int pMy_application_scope_counter)
{
this.my_application_scope_counter = pMy_application_scope_counter;
}
private void salutationObserver(@Observes SalutationEvent event)
{
this.addToCounter();
}
public void addToCounter()
{
this.my_application_scope_counter++;
if (this.my_application_scope_counter % 5 == 0)
{
this.conversation.begin();
this.convStatus.setConversationSattus("on");
}
if (this.my_application_scope_counter > 5 && (this.my_application_scope_counter - 4) % 5 == 0)
{
this.conversation.end();
this.convStatus.setConversationSattus("off");
}
if (this.my_application_scope_counter < 20 && this.isPrime(this.my_application_scope_counter))
{
primeEvent.fire(this.my_application_scope_counter);
}
}
private boolean isPrime(int pNumToCheck)
{
switch (pNumToCheck)
{
case 1:
case 2:
case 3:
case 5:
case 7:
case 11:
case 13:
case 17:
return true;
default:
return false;
}
}
}When the observer is invoked here, the class property conversation is always null. It's even null in the constructor. I must say I'm more than baffled at this one.
@Named("my_conversation_scope_bean")
@ConversationScoped
public class MyConversationScopeBean implements Serializable {
private static final long serialVersionUID = 2346533234L;
private int my_conversation_scope_counter;
@Inject private Conversation conversation;
@Inject public MyConversationScopeBean()
{
this.my_conversation_scope_counter = 0;
}
public int getMy_conversation_scope_counter()
{
return this.my_conversation_scope_counter;
}
public void addToCounter()
{
this.my_conversation_scope_counter++;
}
// Had to have CDI inject the conversation into the observer because the field on the class was always null,
// very strange, talking to the Weld devs about it.
private void salutationObserver(@Observes(notifyObserver=Reception.IF_EXISTS) SalutationEvent event, Conversation pConversation)
{
if (!pConversation.isTransient())
{
this.addToCounter();
}
}
}Any thoughts or ideas from anyone?