1
votes

I'm trying to reuse a jsf page by including using facelets into another jsf page, since this page will be used by a lot of other pages. But the problem is that i can't get the atributes os the managed bean reposible for this page into the managed beans that includes this page.

The page, pessoa.xhtml, some of the repetitive and header code has been removed:

<h:body>
    <div id="pessoa">
        <h:form id="formPessoa">
            <h:messages for="formPessoa"/>

            <h:panelGrid columns="3">
                <h:outputLabel for="id" value="Código: " />
                <h:inputText id="id" value="#{pessoaMB.pessoa.id}"/>
                <h:message for="id" />

                <h:outputLabel for="apelidoNomeFantasia" value="Apelido/Nome Fantasia: " />
                <h:inputText id="apelidoNomeFantasia" value="#{pessoaMB.pessoa.apelidoNomeFantasia}"/>
                <h:message for="apelidoNomeFantasia" />

                <h:outputLabel for="rgIe" value="RG/Inscrição Estadual: " />
                <h:inputText id="rgIe" value="#{pessoaMB.pessoa.rgIe}"/>
            </h:panelGrid>
        </h:form>
    </div>
</h:body>

The @Named managed PessoaMB

@Named
@SessionScoped
public class PessoaMB implements Serializable {

private Pessoa pessoa;

public PessoaMB() {
    this.pessoa = new Pessoa();
} //fim do construtor

public Pessoa getPessoa() {
    return pessoa;
}

public void setPessoa(Pessoa pessoa) {
    this.pessoa = pessoa;
}
}

Here is the code of one of the pages that includes the pessoa.xhtml. empresa.xhtml

<ui:composition template="/resources/template.xhtml">
    <ui:define name="title">
        <h:outputText value="Cadastro de Empresa"/>
    </ui:define>

    <ui:define name="content">
        <h:form id="formEmpresa">
            <ui:include src="/cadastro/pessoa/pessoa.xhtml" />

            <h:commandButton id="novo" action="#{empresaMB.newEmpresa}" value="Novo" />
            <h:commandButton id="salvar" action="#{empresaMB.insert}" value="Salvar" />
        </h:form>
    </ui:define>
</ui:composition>

And the @Named managed bean EmpresaMB.

@Named @SessionScoped public class EmpresaMB implements Serializable {

@EJB
private EmpresaEJBRemote empresaEJB;
private Empresa empresa;
@Inject
private PessoaMB pessoaMB;

public String insert() {
    pessoaMB = this.getPessoaMB();
    empresa.setId(pessoaMB.getPessoa().getId());
    empresaEJB.insert(empresa);
    return "/cadastro/empresa/empresa";
}

public String newEmpresa() {
    pessoaMB = new PessoaMB();
    return "/cadastro/empresa/empresa";
}

//both empresa and pessoaMB getters and setters has been added to the code
}

I think that the @Inject anotation would do the job, but it doesn't.

1
I also would think that @Inject would be used in the bean, why not?Thufir

1 Answers

0
votes

What is exactly the problem? Does the pessoaMB instance variable remains null in EmpresaMB? (i.e. does the initial injection fails?)

Or is the problem that you think that doing the new PessoaMB() will have any effect on the session scoped instance?

This last construct doesn't seem to make sense. Namely, CDI is injecting the EmpresaMB instance with an instance of PessoaMB. This is the exact instance used in the session. However, when you create a new instance in newEmpresa() you are simply overwriting the reference with another instance. This has no connection with the session scoped version whatsoever.

If you want the 'master' bean to produce other beans that gets inserted in its scope, you need to annotate the instance field with the @Named @Produces annotations:

@Named 
@SessionScoped 
public class EmpresaMB implements Serializable {

   @EJB
   private EmpresaEJBRemote empresaEJB;
   private Empresa empresa;

   @Named 
   @Produces
   private PessoaMB pessoaMB;
}

See Reza Rahman's article for some additional details about this: Dependency Injection in Java EE 6: Conversations (Part 4)