I ran into the same problem, and the author’s comment on Primefaces autofill with POJO and String value gave me a hint to find the source of the problem in my case.
overview
The problem is that value=#{objectValue}
is of type String
but the method referenced by completeMethod
returns a List<Object>
.
Design
I have the following POJOs (simplified):
public class CollaboratorGroup { private String groupId; private String groupName; private Collaborator piUserId; ... }
and
public class Collaborator { private String userId; private String fullName; private String groupId; ... }
It doesn't matter if this is a useful design. I just want to solve the problem.
Next p:autoComplete
(simplified):
<p:autoComplete var="group" itemLabel="#{group.groupId}" itemValue="#{group.groupId}" completeMethod="#{bean.completeGroup}" value="#{collaborator.groupId}"> <f:facet name="itemtip"> <p:panelGrid columns="2"> <f:facet name="header"> <h:outputText value="#{group.groupId}" /> </f:facet> <h:outputText value="Name:" /> <h:outputText value="#{group.groupName}" /> <h:outputText value="PI" /> <h:outputText value="#{group.piUserId.fullName}" /> </p:panelGrid> </f:facet> </p:autoComplete>
Will The class 'java.lang.String' does not have the property 'groupId'
. The class 'java.lang.String' does not have the property 'groupId'
. When I change to itemLabel=#{group}
, I see groupId CG00255
in the input field, but many of org.coadd.sharedresources.model.CollaboratorGroup@...
in the drop-down list. If I select one of them, this toString()
value will be set to Collaborator.groupId, which is undesirable.
Source of problem
I p:autoComplete
using List<CollaboratorGroup>
while Collaborator.groupId
is String
and itemLabel
used to “format” both, String groupId
is set to value="#{collaborator.groupId}"
String groupId
value="#{collaborator.groupId}"
and the CollaboratorGroup
obtained from the List
generated by completeMethod="#{bean.completeGroup}"
.
Possible solutions
- You can customize the
Model
by changing the groupId
element to CollaboratorGroup
in Collaborator
if this does not destroy your design. In this case, especially since the CollaboratorGroup
has a Collaborator piUserId
membership. You can simply populate p:autoComplete
List<String> groupIdList
but in this case you need to find another solution for itemtip
.
A very quick solution is to use itemLabel="#{group.class.simpleName eq 'String'? group: group.groupId}"
as mentioned in PrimeCom autocomplete with POJO and String value .
- Problems
- You must take care of
NullPointerExceptions
. - You fill your
View
logic. - This is not a very flexible or dynamic design.
itemLabel="#{bean.printGroupId(group)}"
3. in the bean method itemLabel="#{bean.printGroupId(group)}"
where you have full control over the logic. This is what I did.
public String printGroupId(Object group) { if (group == null) return null; return (group instanceof String) ? (String) group : (group instanceof CollaboratorGroup) ? ((CollaboratorGroup) group).getGroupId() : null; }
(Not the best, just to give you an idea.)
source share