2013-11-19 6 views
1

Я использую JSF 2.0, PrimeFaces и OmniFaces.h: selectManyCheckbox с omnifaces.SelectItemsConverter не предварительно выбирает элементы

У меня есть 2 диалога с <h:selectManyCheckbox>. Первый диалог создает новый Course:

enter image description here

В Disciplina s представлены как:

<h:selectManyCheckbox id="disciplinas" 
    value="#{cursoMBean.listaDisciplinasDoCurso}" 
    converter="omnifaces.SelectItemsConverter"> 
    <f:selectItems value="#{cursoMBean.listaTodasDisciplinas}" 
     var="disciplina" itemValue="#{disciplina}" 
     itemLabel="#{disciplina.nome}" /> 
</h:selectManyCheckbox> 

Это прекрасно работает. Когда я выберу некоторые дисциплины и отправлю форму, то новый Course с выбранным Discipline s правильно вставлен в БД.

Однако, когда я пытаюсь восстановить существующий Course из БД, сохраненные Discipline s не будут предварительно выбраны.

enter image description here

Код тот же:

<h:selectManyCheckbox id="disciplinas" 
    value="#{cursoMBean.listaDisciplinasDoCurso}" 
    converter="omnifaces.SelectItemsConverter"> 
    <f:selectItems value="#{cursoMBean.listaTodasDisciplinas}" 
     var="disciplina" itemValue="#{disciplina}" 
     itemLabel="#{disciplina.nome}" /> 
</h:selectManyCheckbox> 

Вот основа боб:

private ArrayList<Disciplina> listaTodasDisciplinas; 
private ArrayList<Disciplina> listaDisciplinasDoCurso; 

public CursoMBean() { 
    if (listaTodasDisciplinas == null) { 
     listaTodasDisciplinas = controleDisciplina.consulta(); 
    } 

    if (listaDisciplinasDoCurso == null) { 
     listaDisciplinasDoCurso = new ArrayList<Disciplina>(); 
    } 
} 

// When user selects one Course to edit, this method is called: 
public void setSelecionado(Curso selecionado) { 
    this.selecionado = selecionado; 

    if (selecionado != null) { 
     listaTodasDisciplinas = controleDisciplina.consulta(); 
     listaDisciplinasDoCurso = controleCurso.listaDisciplinasAssociadas(selecionado); 
    } 
} 

Вот Disciplina сущность:

public class Disciplina { 

    private int id; 
    private String nome; 

    public Disciplina() { 
    } 

    public Disciplina(int id, String nome) { 
     this.id = id; 
     this.nome = nome; 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getNome() { 
     return nome; 
    } 

    public void setNome(String nome) { 
     if (!(nome.isEmpty() || nome == " " || nome == " ")){ 
      this.nome = nome; 
     } 
    } 

} 

Как это вызвано и как я могу его решить?

+0

Не могли бы вы также показать код своего класса сущности (Disciplina)? – ppawel

+0

Несомненно, подождите, я обновлю вопрос – Paladini

+0

Вопрос обновлен! :) – Paladini

ответ

2

По умолчанию SelectItemsConverter полагается на toString() объекта, который соответствует выбранным элементам. Однако ваша сущность не имеет реализованного toString() и поэтому полагается на результат по умолчанию [email protected], который не совпадает с тем, когда созданы два физически разных экземпляра Disciplina, хотя они имеют одинаковое значение.

Вы имеете в основном 2 варианта, также намекают в SelectItemsConvertershowcase и javadoc:

  1. Реализовать toString метод, который однозначно идентифицирует объект и который имеет смысл в качестве идентификатора. Например,

    @Override 
    public String toString() { 
        return String.format("%s[id=%d]", getClass().getSimpleName(), getId()); 
    } 
    

    (обратите внимание, что эта toString() разработана таким образом, что вы можете легко держать его в абстрактный базовый класс всех сущностей, так что вам не нужно CopyPaste одинаково во всех субъектов)

  2. Или, если внедрение такого toString() по какой-либо причине не является вариантом (например,опираясь на сгенерированные классы, которые не могут быть изменены впоследствии (ни эталонный генератор)), а затем продлить преобразователь следующим образом:

    @FacesConverter("disciplinaSelectItemsConverter") 
    public class DisciplinaSelectItemsConverter extends SelectItemsConverter { 
    
        @Override 
        public String getAsString(FacesContext context, UIComponent component, Object value) { 
         Integer id = (value instanceof Disciplina) ? ((Disciplina) value).getId() : null; 
         return (id != null) ? String.valueOf(id) : null; 
        } 
    
    } 
    

    (примечание: вы действительно должны использовать Integer вместо int в качестве идентификатора, то int не может быть null что правильный способ представить совершенно новый и unpersisted сущность)

    и использовать его следующим образом

    <h:selectManyCheckbox ... converter="disciplinaSelectItemsConverter"> 
    
+0

Еще раз спасибо BalusC! Сегодня утром я решил этот вопрос. Я быстро исправился и теперь работает - но это именно то, что вы делаете, но более сложно реализовать. Итак, опять же, вы лучший ответ: P – Paladini