Search code examples
jsfjsf-2cdiview-scope

Inject CDI bean into JSF @ViewScoped bean


I have a problem with JSF, CDI project. I did a lot of research and I found that in CDI there is no @ViewedScoped annotation. I solving problem with ajax based page with dialog. I want to pass variable to dialog from datatable. For this purpose, I can't use @RequestedScoped bean because value is discard after end of request. Can anyone help me to solve it? I can't use @SessionScoped but it's a bad practice IMHO. Or maybe save only this one variable into session who knows. Can you guys give me any hints how to solve this problem elegantly?

import javax.enterprise.context.ApplicationScoped;    
@ApplicationScoped
public class ServiceBean implements Serializable {
...
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class SomeBean {

@Inject
ServiceBean serviceBean;


@Postconstruct ...

Here is the error message:

com.sun.faces.mgbean.ManagedBeanCreationException: An error occurred performing resource injection on managed bean warDetailBean

Solution

  • First, If you are attempting to use CDI, you need to activate it by putting a WEB-INF/beans.xml file in your application (note that this file can be empty), more informations about that file could be found in the Weld - JSR-299 Reference Implementation.

    As you are using Tomcat, please be sure to respect all the configuration requirements by following the steps in How to install CDI in Tomcat?

    Second, Even if you can use @Inject inside a JSF managed bean, It's preferable that you don't mix JSF managed beans and CDI, please see BalusC's detailed answer regarding Viewscoped JSF and CDI bean.

    So if you want to work only with CDI @Named beans, you can use OmniFaces own CDI compatible @ViewScoped:

    import javax.inject.Named;
    import org.omnifaces.cdi.ViewScoped;
    
    @Named
    @ViewScoped
    public class SomeBean implements Serializable {
    
        @Inject
        ServiceBean serviceBean;
    }
    

    Or, if you want to work only with JSF managed beans, you can use @ManagedProperty to inject properties:

    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    @ManagedBean
    @ViewScoped
    public class SomeBean{
    
    @ManagedProperty(value = "#{serviceBean}")
    ServiceBean serviceBean;
    
    }
    

    See also: