Автозаполнение Primefaces удаляет значения после перезагрузки страницы

я столкнулся с довольно странной проблемой. На самом деле я использую автозаполнение primfaces (6.0) с несколькими значениями.
Все работает так, как ожидалось, за исключением одного маленького неприятного вопроса. Как только я сохранил свои данные и перезагрузил страницу (оставив область), похоже, все хорошо, но значения в моем multiselect disapear, как только выберите новый.
Например, список выглядит так после перезагрузки страницы:

Value1 Value2 Value3

Как только a теперь введите поле и выберите Value4 список выглядит так:

Value4

Все остальные ценности исчезают, даже если они изначально существуют.

Здесь некоторый код (XHTML)

<p:autoComplete multiple="true" value="#{pricelistItemBean.newPricelistItem.subItems}" completeMethod="#{pricelistItemBean.completeItems}"
            var="pl" itemLabel="#{pl.name}" itemValue="#{pl}"
            converter="#{couchbaseEntityConverter}" forceSelection="true" cache="true" >
<p:column>
    <h:outputText value="#{pl.name}"/>
</p:column>
<p:column>
    <h:outputText value="#{pl.description}"/>
</p:column>

Это конвертер:

@Named
@Scope("session")
public class CouchbaseEntityConverter implements Converter {

public static final int SIMPLE_CACHE_SIZE = 20;
private Map<String, CBMain> entities = new HashMap<>(SIMPLE_CACHE_SIZE);
@Autowired
CouchbaseRepository couchbaseRepository;

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (value != null && value.length() > 0) {
        if (entities.containsKey(value)) {
            return entities.get(value);
        } else {
            CBMain entity = couchbaseRepository.findById(value, CBMain.class);
            if (entities.size() >= SIMPLE_CACHE_SIZE) {
                List<String> list = new ArrayList<>(entities.keySet());
                entities.remove(list.get(list.size() - 1));
            }
            entities.put(value, entity);
            return entity;
        }
    } else {
        return null;
    }
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value != null && value instanceof CBMain) {
        return ((CBMain) value).getId();
    }
    return null;
}

public Map<String, CBMain> getEntities() {
    return entities;
}

}

Сущность в основном просто загружается как
@PostConstruct

Вещи, которые я сделал:

  • Я скопировал список (значения автозаполнения) в @PostConstructметоде просто для проверки. Их список однозначно задан и корректен.

  • я проверил события itemSelect / itemUnselect. Здесь, возможно, стоит отметить, что как только itemUnselect-событие инициируется, список возвращается к пустому списку уже

  • если я добавляю / удаляю только элементы после загрузки страницы, все работает так, как ожидалось.

Я использую Spring / Tomcat 8 / JSF2.2 / Couchbase и я вроде как заканчиваются идеи.. любая помощь будет высоко оценена.

Спасибо!

1 ответ

  1. Неважно, спасибо всем, кто проверил этот вопрос.
    Решение (конечно) очень простое.

    Фактически couchbase (spring-couchbase) не хранит ID (если аннотирован как @Id) в JSON-объекте. (его сохранили как META (bucket).id)

    Это снова означает, что мой список объектов в основном выглядел так:

     {
        prop1:"val1",
        prop2:"val2",
        subItems: {
           prop1:"val1",
           prop2:"val2"
        }
     }
    

    Этот JSON, преобразованный в POJO, сделал мой конвертер довольно бесполезным, так как я ожидал, что json будет выглядеть так:

        subItems: {
           id: "myId...",
           prop1:"val1",
           prop2:"val2"
        }
    

    Итак, наличие ID. Который был просто не тот случай, и это вызвало

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value != null && value instanceof CBMain) {
        return ((CBMain) value).getId();
    }
    return null;
    

    }

    всегда возвращать null ….