Я столкнулся с той же проблемой, и комментарий автора на Автозаполнение Primefaces с POJO и значением String подсказало мне найти источник проблемы в моем случае.
Обзор
Проблема в том, что value=#{objectValue}
имеет тип String
, но метод, на который ссылается completeMethod
, возвращает List<Object>
.
Дизайн
У меня есть следующие POJO (упрощенно):
public class CollaboratorGroup {
private String groupId;
private String groupName;
private Collaborator piUserId;
...
}
и
public class Collaborator {
private String userId;
private String fullName;
private String groupId;
...
}
Не имеет значения, полезный ли это дизайн. Я просто хочу решить проблему.
Следующее p:autoComplete
(упрощенно):
<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>
бросит The class 'java.lang.String' does not have the property 'groupId'
. Когда я изменяю на itemLabel=#{group}
, я вижу groupId CG00255
в поле ввода, но многие из org.coadd.sharedresources.model.CollaboratorGroup@...
в раскрывающемся списке. Если я выберу один из них, это значение toString()
будет установлено на Collaborator.groupId, что нежелательно.
Источник проблемы
Я кормлю p:autoComplete
List<CollaboratorGroup>
, в то время как Collaborator.groupId
является String
, а itemLabel
используется для «форматирования» обоих: String groupId
, установленный как value="#{collaborator.groupId}"
и CollaboratorGroup
, который происходит от List
, сгенерированного completeMethod="#{bean.completeGroup}"
.
Возможные решения
- Вы можете настроить
Model
, изменив элемент groupId
на CollaboratorGroup
в Collaborator
, если он не разрушает ваш дизайн. В этом случае, тем более что CollaboratorGroup
имеет член Collaborator piUserId
.
Вы можете просто заполнить p:autoComplete
List<String> groupIdList
, но в этом случае вам нужно найти другое решение для itemtip
.
Очень быстрое решение - использовать itemLabel="#{group.class.simpleName eq 'String' ? group : group.groupId}"
, как указано в Primefaces, автозаполнение с POJO и значением String .
- Проблемы
- Вы должны заботиться о
NullPointerExceptions
.
- Вы заполняете свой
View
логикой.
- Это не очень гибкий или динамичный дизайн.
Реализация 3. в методе bean itemLabel="#{bean.printGroupId(group)}"
, где вы имеете полный контроль над логикой. Это то, что я сделал.
public String printGroupId(Object group) {
if (group == null) return null;
return (group instanceof String) ? (String) group : (group instanceof CollaboratorGroup) ? ((CollaboratorGroup) group).getGroupId() : null;
}
(Не самый лучший, просто чтобы дать вам представление.)