1

私はJSF 2.0、PrimeFacesおよびOmniFacesを使用しています。

とのダイアログが 2 つあります<h:selectManyCheckbox>。最初のダイアログは新しい を作成しますCourse:

ここに画像の説明を入力

Disciplina次のように表されます。

<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と、選択したDisciplines を含む新しいものが DB に適切に挿入されます。

ただし、DB から既存のものを取得しようとするとCourse、保存されたDisciplines が事前に選択されていません。

ここに画像の説明を入力

コードは同じです:

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

バッキング Bean は次のとおりです。

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;
        }
    }

}

これはどのように発生し、どうすれば解決できますか?

4

1 に答える 1

2

デフォルトでは、選択されたアイテムと一致するエンティティのSelectItemsConverter依存関係。toString()ただし、エンティティには実装されていないため、値が同じであっても物理的に異なる2つのインスタンスが作成された場合、同じではないtoString()デフォルトの結果に依存しています。fqn@hashcodeDisciplina

基本的に 2 つのオプションがあり、SelectItemsConverter showcasejavadocにもヒントが示されています。

  1. toStringエンティティを一意に識別し、識別子として意味のあるメソッドを実装します。例えば、

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

    (これtoString()は、すべてのエンティティの抽象基本クラスに簡単に保持できるように設計されているため、すべてのエンティティに同じものをコピーペーストする必要がないことに注意してください)

  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;
        }
    
    }
    

    (注: ID のInteger代わりに実際に使用する必要があります。これは、真新しく永続化されていないエンティティを表す正しい方法ではありません)intintnull

    そして、次のように使用します

    <h:selectManyCheckbox ... converter="disciplinaSelectItemsConverter">
    
于 2013-11-19T11:01:12.343 に答える