SelectManyCheckbox returns array of Object[] instead of ArrayList

55 Views Asked by At

Im trying to bind the selected values of a p:selectManyCheckbox to an ArrayList, even tho what is happenening is that it builds an Object[] array.

project info

Java 17 Springboot 3.2.3 Primefaces 13.0.7:jakarta Mojarra 4.0.5 Joinfaces 5.2.3

MyBean

@Component
@ViewScoped
public class MyBean {
    @Autowired
    Service service;
    Selections selections;
    ArrayList<Dto> dtoList;
    Map<String, List<MyItem>> myMap;
    @PostConstruct
    public void init() {
        selections = service.loadSelections();
        Dto dto1 = new Dto("NEW1");
        dto1.setCheckedItems(new ArrayList<Myitem>());
        Dto dto2 = new Dto("NEW2");
        dto2.setCheckedItems(new ArrayList<Myitem>());
        myMap = new HashMap<String, List<MyItem>>();
        myMap.put(dto1.getId(),new ArrayList<MyItem>());
        myMap.put(dto2.getId(),new ArrayList<MyItem>());
    }
    //getters and setters
}

Selections

public class Selections {
    List<MyItem> myItems;
    //default constructor
    //getters and setters
}

Service

@Service
public class Service {
    @Autowired
    MyRestClient restclient;
    
    public Selections loadSelections() {
        Selections s = new Selections();
        //i reach endpoint myItem/list
        //return value type is : List<MyItem>
        s.setMyItems = restclient.getMyItems(); 
    }
}

Xhtml

<ui:repeat var="dto" value="#{myBean.dtoList}" varStatus="dtoStatus">
    <ui:param name="indexDto" value="#{dtoStatus.index}" />
    <p:selectManyCheckbox value="#{myBean.myMap[dto.id]}" 
        collectionType="java.util.ArrayList"
        layout="responsive" columns="6" converter="generalConverter">
        <p:ajax process="@this" />
        <f:selectItems
            value="#{myBean.selections.myItems}"
            var="item" itemLabel="#{item.description}" itemValue="#{item}" />
    </p:selectManyCheckbox>
</ui:repeat>

GeneralConverter

@FacesConverter(value = "generalConverter" , forClass = GeneralConverter.class )
public class GeneralConverter implements Converter {

    private static Map<Object, String> entities = new WeakHashMap<Object, String>();

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        synchronized (entities) {
            if (!entities.containsKey(value)) {
                String uuid = UUID.randomUUID().toString();
                entities.put(value, uuid);
                return uuid;
            } else {
                return entities.get(value);
            }
        }
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        for (Entry<Object, String> entry : entities.entrySet()) {
            if (entry.getValue().equals(value)) {
                return entry.getKey();
            }
        }
        return value;
    }

}

after toggling the checkboxes.

List selectedOptions contains Object[] array containing MyItem

i tried to store the values in MyItem[] arr; but the it will still be of Object[] type. i also tried to store the values of selectedOptions into an Array<Objects[]> i will get a class cast exception anyway...

i also tried to add collectionType="java.util.ArrayList" attribut to selectManyCheckbox

Stacktrace example

akarta.faces.FacesException: #{nuovoContratto.debug()}: /auth/operazioni/nuovoContratto.xhtml @370,64 action="#{nuovoContratto.debug()}": java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Lit.qi.mywebapp.company.model.AnagraficaEmettitoreDto; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [Lit.qi.mywebapp.company.model.AnagraficaEmettitoreDto; is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @25335b81)
    at com.sun.faces.application.ActionListenerImpl.getNavigationOutcome(ActionListenerImpl.java:83) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:62) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at jakarta.faces.component.UICommand.broadcast(UICommand.java:205) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at com.sun.faces.facelets.component.UIRepeat.broadcast(UIRepeat.java:966) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at jakarta.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:858) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at jakarta.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1332) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:56) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:72) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:131) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at jakarta.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:691) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at jakarta.faces.webapp.FacesServlet.service(FacesServlet.java:449) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) ~[spring-security-web-6.2.2.jar:6.2.2]
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) ~[spring-webmvc-6.1.4.jar:6.1.4]
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) ~[spring-security-config-6.2.2.jar:6.2.2]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) ~[spring-web-6.1.4.jar:6.1.4]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.4.jar:6.1.4]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: jakarta.el.ELException: /auth/operazioni/nuovoContratto.xhtml @370,64 action="#{nuovoContratto.debug()}": java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Lit.qi.mywebapp.company.model.AnagraficaEmettitoreDto; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [Lit.qi.mywebapp.company.model.AnagraficaEmettitoreDto; is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @25335b81)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:76) ~[jakarta.faces-4.0.5.jar:4.0.5]
    at com.sun.faces.application.ActionListenerImpl.getNavigationOutcome(ActionListenerImpl.java:74) ~[jakarta.faces-4.0.5.jar:4.0.5]
    ... 90 common frames omitted
Caused by: java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Lit.qi.mywebapp.company.model.AnagraficaEmettitoreDto; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [Lit.qi.mywebapp.company.model.AnagraficaEmettitoreDto; is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @25335b81)
    at java.base/java.util.HashMap.forEach(HashMap.java:1421) ~[na:na]
    at it.qi.mywebapp.view.contratto.NuovoContratto.buildContratto(NuovoContratto.java:177) ~[main/:na]
    at it.qi.mywebapp.view.contratto.NuovoContratto.debug(NuovoContratto.java:172) ~[main/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.apache.el.parser.AstValue.invoke(AstValue.java:253) ~[tomcat-embed-el-10.1.19.jar:10.1.19]
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:267) ~[tomcat-embed-el-10.1.19.jar:10.1.19]
    at org.jboss.weld.module.web.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) ~[weld-web-5.1.2.Final.jar:5.1.2.Final]
    at org.jboss.weld.module.web.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) ~[weld-web-5.1.2.Final.jar:5.1.2.Final]
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:70) ~[jakarta.faces-4.0.5.jar:4.0.5]
    ... 91 common frames omitted

I think that this is question is the closest to my issue, but i dont know if after many years something improved

#My current workaround I store my objects into an array of MyItem[] then parse it and cast it's content to the desired type

private Map<String, Myitem[]> myMap;

ArrayList<MyItem> = MyBean.arrayCast(myMap.get(key));

private static <T> List<T> arrayCast(Object[] array) {
        List<T> list = new ArrayList<T>();
        for(int i = 0; i<array.length; i++) {
            list.add((T) array[i]);
        };
        return list;
}

this is what i tried to do in my service, nothing special.

public Selections loadSelections() {
        Selections selections = new Selections();
        AnagraficaEmettitoreDto an1 = new AnagraficaEmettitoreDto();
        AnagraficaEmettitoreDto an2 = new AnagraficaEmettitoreDto();
        an1.setDescrizione("test1");
        an2.setDescrizione("test2");
        ArrayList<AnagraficaEmettitoreDto> arrlist = new ArrayList<AnagraficaEmettitoreDto>();
        arrlist.add(an1);
        arrlist.add(an2);
        selections.setAnagraficaEmettitoreDtos(arrlist);
        return selections;
}

this is what i try to do when i trigger debug() with a commandbutton. i get a class cast exception during loop

public void debug() {
        ArrayList<ArrayList<AnagraficaEmettitoreDto>> arrlist = new ArrayList<ArrayList<AnagraficaEmettitoreDto>>();
        myMap.forEach((k,v)-> arrlist.add(v));
        System.out.println("debug");
    }

#Further tests from a fresh maven-jar-starter project

@Component
@ViewScoped
@Getter
@Setter
public class TestView {
    Map<String, ArrayList<Dto>> map;
    ArrayList<String> strings;
    ArrayList<Dto> options;
    @PostConstruct
    public void init() {
        Dto dto1 = new Dto();
        Dto dto2 = new Dto();
        dto1.setAge(1);
        dto1.setName("OPTION1");
        dto2.setAge(2);
        dto2.setName("OPTION2");
        options = new ArrayList<Dto>();
        options.add(dto1);
        options.add(dto2);
        map = new HashMap<String, ArrayList<Dto>>();
        strings = new ArrayList<String>();
        strings.add(new String("TEST1"));
        strings.add(new String("TEST2"));
        
        strings.forEach(s -> map.put(s, new ArrayList<Dto>()));
    }
    public void debug() {
        System.out.println("debug");
        ArrayList<ArrayList<Dto>> testarr = new ArrayList<ArrayList<Dto>>();
        map.forEach((k,v)->testarr.add(v));
    }
    
}

Dto

public class Dto {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

xhtml

ui:repeat var="str" value="#{testView.strings}" varStatus="strStatus">
    <ui:param name="indexStr" value="#{strStatus.index}" />
    <p:selectManyCheckbox value="#{testView.map[str]}"
        converter="org.joinfaces.example.view.MyConverter" layout="responsive" columns="6">
        <p:ajax process="@this" />
        <f:selectItems value="#{testView.options}" var="item"
            itemLabel="#{item.name}" itemValue="#{item}" />
    </p:selectManyCheckbox>
</ui:repeat>
<p:commandButton value="debug" icon="pi pi-check" process="@this"
    action="#{testView.debug()}" />

Converter

@FacesConverter("org.joinfaces.example.view.Converter")
public class MyConverter implements Converter<Dto> {

    private Map<Dto, String> entities = new HashMap<Dto, String>();

    @Override
    public String getAsString(FacesContext context, UIComponent component, Dto value) {
        synchronized (entities) {
            if (!entities.containsKey(value)) {
                String uuid = UUID.randomUUID().toString();
                entities.put(value, uuid);
                return uuid;
            } else {
                return entities.get(value);
            }
        }
    }

    @Override
    public Dto getAsObject(FacesContext context, UIComponent component, String value) {
        for (Map.Entry<Dto, String> entry : entities.entrySet()) {
            if (entry.getValue().equals(value)) {
                return entry.getKey();
            }
        }
        return null;
    }
}
0

There are 0 best solutions below