'Why selected items is always empty in the Bean for Primefaces selectCheckboxMenu

I am using selectCheckboxMenu from Primefaces in a JSF project, the problem is that the "selectedDepartments" object in the Bean is always empty. Here is the code:

Xhtml Page

<p:selectCheckboxMenu id="menu"  label="name" style="width: 15rem"  converter="#{departmentConverter}" value="#{StudentMB.selectedDepartments}"
                             multiple="true" filter="true" filterMatchMode="startsWith" panelStyle="width: 15rem" scrollHeight="250" >
    <c:selectItems value="#{StudentMB.departmentList}" var="department" itemLabel="#{department.name}" itemValue="#{department}"/>      
    <p:ajax event="change"  process="@this" update=":form2:dt-Students" global="false"/>
</p:selectCheckboxMenu>

The converter for selectCheckboxMenu:

@Named
@FacesConverter(value = "departmentConverter")
public class departmentConverter implements Converter {

    @Inject
    private departmentDAO departmentDAO;
    
    @Override
    public department getAsObject(FacesContext context, UIComponent component, String value) {
        if (value != null && value.trim().length() > 0) {
            try {
                department c= departmentDAO.getdepartmentById(Integer.parseInt(value));
                return c;
            }
            catch (NumberFormatException e) {
                throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid country."));
            }
        }
        else {
            return null;
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value != null) {
            department c=(department)value;
            return String.valueOf(c.getId());
        }
        else {
            return null;
        }
    }
    
    
}

The code of the Managed Bean

public class StudentMB implements Serializable{ 
    private LazyDataModel<Student> lazyModel = null;
    private List<department> departmentList;
    private List<department> selectedDepartments;   
    @Inject
    private departmentDAO departmentDAO;   
    
    @PostConstruct
    public void init() {
        
    this.selectedDepartments= new ArrayList<>();
    this.departmentList= new ArrayList<>();
    this.departmentList = this.departmentDAO.listDepartments();
    
    lazyModel = new StudentLazyList(StudentDAO){
        @Override
        public List<Student> load(int first, int pageSize, Map<String, SortMeta> sortBy, Map<String, FilterMeta> filterBy) {
                return load2(first, pageSize, sortBy, filterBy,selectedDepartments);
            }
        };
    }
}

Thanks for help.



Solution 1:[1]

The solution is found for those who encounter the same problem. it was relative to the converter, indeed I don't know why we have to use a converter when it comes to a Pojo class because we already mentioned the name of class in the value property of selectItems. Nevermind , here is the code that works

The selectCheckboxMenu component

<h:form id="form1">                 
    <p:selectCheckboxMenu id="menu"  label="department" converter="departmentConverter" value="#{studentMB.selectedDepartments}"
                             multiple="true" filter="true" filterMatchMode="startsWith" style="width: 15rem" panelStyle="width: 15rem" scrollHeight="250" >
            <c:selectItems value="#{studentMB.departmentList}" var="department" itemLabel="#{department.name}" itemValue="#{department}"/>        
            <p:ajax event="change" update=":form2:dt-students"/>
    </p:selectCheckboxMenu>                   
</h:form>

The converter class

@Named
@FacesConverter(value = "departmentConverter")
public class DepartmentConverter implements Converter {
     
    @Override
    public Department getAsObject(FacesContext context, UIComponent component, String value) {
              
        if(value == null)
            return null;
 
        StudentMB data = context.getApplication().evaluateExpressionGet(context, "#{studentMB}", StudentMB.class);
        int actualId=Integer.parseInt(value);
        for(Department dep : data.getDepartmentList())
        {
            if(categ.getId()==actualId)
                return dep;
        }       
             
        throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid department."));       
  
    }
 
    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value != null) {
          Department c=(Department)value;
            return String.valueOf(c.getId());
        }
        else {
            return null;
        }
    }   
     
}

Hope this help

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dev Learning