<rich:pickList> - ajuda

Hei people,
é a primeira vez que me aventuro na utilização desse <rich:pickList>. Estou utilizando-o para praticar o conhecimento que adquiri nos estudos de Java (recentemente).

A questão é a seguinte:
Criei no meu banco uma tabela de Lojas (populada), e uma tabela de Compras. Na hora de cadastrar Compras eu tenho que selecionar as lojas em que fiz as compras.

O meu jsf está assim:

&lt;rich:pickList copyAllControlLabel=" Copiar tudo" copyControlLabel="Copiar" removeControlLabel="Remover" removeAllControlLabel="Remover tudo" value="#{listaLojasSelecionadas}"&gt;
   &lt;f:selectItems value="#{listaComboLojas}"/&gt;
&lt;/rich:pickList&gt;

Na action fiz o seguinte:

@In(required = false)
@Out(required = false)
List&lt;SelectItem&gt; listaComboLojas = new ArrayList&lt;SelectItem&gt;();
	
@In(required = false)
@Out(required = false)
List&lt;String&gt; listaLojasSelecionadas = new ArrayList&lt;String&gt;();

public List&lt;Loja&gt; listaLoja(){
	List&lt;Loja&gt; lista = null;
	lista = entityManager.createNamedQuery("listaLojas").getResultList();			
	//--------------------------------------------------------------------------------------------------------------------//
	for(Loja loja : lista){
		listaComboLojas.add(new SelectItem(loja.getIdLoja().toString(),loja.getNomeLoja()));
	}	
	//--------------------------------------------------------------------------------------------------------------------//
	return lista;
}

Entity Loja

@Entity
@Table(name = "Loja", schema = "Estudo")
@NamedQueries({ @NamedQuery(name = "listaLojas", query = "SELECT OBJECT(loja) FROM Loja loja") })
public class Loja implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Id
	@Column(name = "idLoja", unique = true, nullable = false)
	private Integer idLoja;

	@Column(name = "nomeLoja")
	private String nomeLoja;
	
	@ManyToMany
	@JoinTable(schema = "cvp", name = "Compra_has_Loja", joinColumns = { @JoinColumn(name = "idLoja") }, inverseJoinColumns = { @JoinColumn(name = "idCompra") })
	private List&lt;Compra&gt; compras;
...
}

Ele está gerando o seguinte erro:
Value of tag <selectItems> attribute is incorrect.

Eu num tenho que passar uma lista de SelectItem?

Aponte para meu ManagedBean: #{seuManagedBean.listaComboLojas}

Dá problema jakefrog. Quando eu coloco o meu managedBean ele não me dá a opção listaComboLojas.

você vai precisar de um converter para seus objetos na lista, sem ele seu picklist não sabe quel tipo de atributo pegar so seu objeto, porque por default deve ser uma String como visto na referência do componente:
"If the itemValue of the SelectItem is not of type String, a converter must be specified for this itemValue using either the converter attribute, or a nested <f:converter> tag. "

<rich:pickList value="#{listSelectBean.selectedCapitals}"

               sourceCaption="Available cities" targetCaption="Selected cities"

               listWidth="170px" listHeight="100px"

               orderable="true">

    <f:selectItems value="#{listSelectBean.capitals}" var="capital" itemValue="#{capital}" itemLabel="#{capital.name}" />

    <f:converter converterId="CapitalsConverter" />

</rich:pickList>

[quote=satangoss]você vai precisar de um converter para seus objetos na lista, sem ele seu picklist não sabe quel tipo de atributo pegar so seu objeto, porque por default deve ser uma String como visto na referência do componente:
"If the itemValue of the SelectItem is not of type String, a converter must be specified for this itemValue using either the converter attribute, or a nested <f:converter> tag. "

[code]
<rich:pickList value="#{listSelectBean.selectedCapitals}"

           sourceCaption="Available cities" targetCaption="Selected cities"

           listWidth="170px" listHeight="100px"

           orderable="true">

<f:selectItems value="#{listSelectBean.capitals}" var="capital" itemValue="#{capital}" itemLabel="#{capital.name}" />

<f:converter converterId="CapitalsConverter" />

</rich:pickList>

[/code][/quote]

satangoss, quando eu coloco <f:selectItems …> ele não me dá essas opções que vc colocou (var, itemValue, itemLabel).

Como vc fez para aparecer?

[quote=diogo_Jr][quote=satangoss]você vai precisar de um converter para seus objetos na lista, sem ele seu picklist não sabe quel tipo de atributo pegar so seu objeto, porque por default deve ser uma String como visto na referência do componente:
"If the itemValue of the SelectItem is not of type String, a converter must be specified for this itemValue using either the converter attribute, or a nested <f:converter> tag. "

[code]
<rich:pickList value="#{listSelectBean.selectedCapitals}"

           sourceCaption="Available cities" targetCaption="Selected cities"

           listWidth="170px" listHeight="100px"

           orderable="true">

<f:selectItems value="#{listSelectBean.capitals}" var="capital" itemValue="#{capital}" itemLabel="#{capital.name}" />

<f:converter converterId="CapitalsConverter" />

</rich:pickList>

[/code][/quote]

satangoss, quando eu coloco <f:selectItems …> ele não me dá essas opções que vc colocou (var, itemValue, itemLabel).

Como vc fez para aparecer?[/quote]

deve ser sua versão do richfaces, alguns paramêtros são modificados de uma versão para a outra, eu utilizo a versão 4.1 (a mais nova), verifique na documentação de referência de desenvolvedor da sua versão. Mas a questão do converter funciona do mesmo jeito independente da versão do richfaces.

Estou utilizando a versão 3.3

verifique aqui a documentação da sua versão.

Eu posso utilizar o <s:selectItems …> em vez do <f:selectItems …>, pois o <s:selectItems> tem essas outras opções?

acho que sim, mas é estranho não aparecerem, qual versão do JSF vc ta usando?

acho que sim, mas é estranho não aparecerem, qual versão do JSF vc ta usando?[/quote]
JSF2 Na minha tag <f:selectItems> aparece as seguintes opções: binding, id e value.

satangoss, alterei a minha action para:

public List&lt;String&gt; listaLoja(){  
    List&lt;Loja&gt; lista = null;  
    List&lt;String&gt; novaLista = new ArrayList&lt;String&gt;();
    lista = entityManager.createNamedQuery("listaLojas").getResultList();             
//--------------------------------------------------------------------------------------------------------------------//  
    for(Loja loja : lista){  
        novaLista.add(loja.nomeLoja);  
    }     
    //--------------------------------------------------------------------------------------------------------------------//  
    return novaLista;  
}

Ele carregou o pickList, só que não passa o nome da Loja, tipo, vem a quantidade de lojas que tem só que tudo null.

esqueci de dizer que eu mudei o meu xhtml:

&lt;rich:pickList id="listaLoja" copyAllControlLabel=" Copiar Tudo" copyControlLabel="Copiar" removeControlLabel="Remover" removeAllControlLabel="Remover Tudo" style="font-size: 14px;"&gt;
&lt;s:selectItems value="#{compraAction.listaLojas()}" var="loja" itemValue="#{loja}" itemLabel="#{loja.nomeLoja}"/&gt;
&lt;/rich:pickList&gt;

Obs.: fiz o debbug e está tudo ok. ele passa o nome da loja para a lista de String.

[quote=diogo_Jr]esqueci de dizer que eu mudei o meu xhtml:

&lt;rich:pickList id="listaLoja" copyAllControlLabel=" Copiar Tudo" copyControlLabel="Copiar" removeControlLabel="Remover" removeAllControlLabel="Remover Tudo" style="font-size: 14px;"&gt;
&lt;s:selectItems value="#{compraAction.listaLojas()}" var="loja" itemValue="#{loja}" itemLabel="#{loja.nomeLoja}"/&gt;
&lt;/rich:pickList&gt;

Obs.: fiz o debbug e está tudo ok. ele passa o nome da loja para a lista de String.[/quote]
sim porém se esta utilizando um selectItems você deve ter uma lista de selectItems no retorno do seu metodo, mais ou menos assim:

public List&lt;SelectItem&gt; getListaLojas() {

   private List&lt;SelectItem&gt; lojaItens = new ArrayList&lt;SelectItem&gt;() ;


            Loja l1 = new Loja("1", "Loja1");
            Loja l2 = new Loja("2", "Loja2");
            Loja l3 = new Loja("3", "Loja3");
            Loja l4 = new Loja("4", "Loja4");
            Loja l5 = new Loja("5", "Loja5");
          
          

          
            lojaItens.add(new SelectItem(l1, p1.getNome()));
            lojaItens.add(new SelectItem(l2, p2.getNome()));
           .
           .
           . 
            
   

        return this.lojaItens;
    }

Fiz assim:

public List&lt;SelectItems&gt; listaLoja(){    
        List&lt;Loja&gt; lista = null;    
        List&lt;SelectItems&gt; novaLista = new ArrayList&lt;String&gt;();  
        lista = entityManager.createNamedQuery("listaLojas").getResultList();               
    //--------------------------------------------------------------------------------------------------------------------//    
        for(Loja loja : lista){    
            novaLista.add(new SelectItem(loja.getIdLoja().toString(), loja.getNomeLoja()));    
        }       
        //--------------------------------------------------------------------------------------------------------------------//    
        return novaLista;    
    }

continuou o mesmo problema. Acho que é o meu xhtml. Vou dar uma pesquisada melhor aki.

consegui fazer ele popular corretamente a minha pickList, só que na hora que eu vou salvar ele me retorna a seguinte msg:

ValueBinding for UISelectMany must be of type List or Array.

o meu xhtml ficou assim:

&lt;rich:pickList value="#{listaLojasSelecionadas}"&gt;
	&lt;f:selectItems value="#{compraAction.listaLojas()}"/&gt;
&lt;/rich:pickList&gt;

a minha listaLojasSelecionadas é uma lista de selectItem.

People,
tinha dado uma pausa no meu ‘treinamento’ de java, pois tive que fazer uma viagem, mas agora voltei. É o seguinte, o erro anterior (ValueBinding for UISelectMany must be of type List or Array.) já consegui arrumar, só que esse aqui me fez empacar.

ERRO:
javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of org.domain.cadastro.entity.Loja.idLoja

Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of org.domain.cadastro.entity.Loja.idLoja

Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Integer field org.domain.cadastro.entity.Loja.idLoja to java.lang.String

Olhei algumas soluções postadas aqui mesmo no guj só que não consegui entender. As minhas classes estão assim:
ENTITY COMPRA

@Entity
@Table(name = "Compra", schema = "Estudo")
@NamedQueries({ @NamedQuery(name = "compra.Lista", query = "SELECT OBJECT(compra) FROM Compra compra") })
public class Compra implements Serializable {

	private static final long serialVersionUID = 1L;

	private Date dataCompra;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "idCompra", unique = true, nullable = false)
	private Integer idCompra;

	@Temporal(TemporalType.DATE)
	@Column(name = "dataCompra")
	public Date getDataCompra() {
		return dataCompra;
	}

[...]
	
	@ManyToMany
	@JoinTable(schema = "cvp", name = "Compra_has_Loja", joinColumns = { @JoinColumn(name = "idCompra") }, inverseJoinColumns = { @JoinColumn(name = "idLoja") })
	private List&lt;Loja&gt; lojas;

[...]
        public List&lt;Loja&gt; getLojas() {
		return lojas;
	}

	public void setLojas(List&lt;Loja&gt; lojas) {
		this.lojas = lojas;
	}

ENTITY LOJA

@Entity
@Table(name = "Loja", schema = "cvp")
@NamedQueries({ @NamedQuery(name = "loja.Lista", query = "SELECT OBJECT(loja) FROM Loja loja") })
public class Loja implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "idLoja", unique = true, nullable = false)
	private Integer idLoja;

[...]
	@ManyToMany
	@JoinTable(schema = "cvp", name = "Compra_has_Loja", joinColumns = { @JoinColumn(name = "idLoja") }, inverseJoinColumns = { @JoinColumn(name = "idCompra") })
	private List&lt;Compra&gt; compras;

[...]
	public List&lt;Compra&gt; getCompras() {
		return compras;
	}

	public void setCompras(List&lt;Compra&gt; compras) {
		this.compras = compras;
	}

ACTION

[...]
	@In(required = false)
	@Out(required = false)
	List&lt;Loja&gt; listaLojasSelecionadas = new ArrayList&lt;Loja&gt;(); 

        public void salvarCompra() {
		try {
			this.compraManager.salvarCompra(this.compra);
			this.statusMessages.add("Compra salva com sucesso!");
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.compra = null;
		this.novaCompra();
	}

[...]
	public List&lt;Loja&gt; getListaLojasSelecionadas() {
		return listaLojasSelecionadas;
	}

	public void setListaLojasSelecionadas(List&lt;Loja&gt; listaLojasSelecionadas) {
		this.listaLojasSelecionadas = listaLojasSelecionadas;
	}

PARTE DO XHTML:

[...]
    		&lt;h:outputText value="Lojas:" style="font-weight: 700;"/&gt;
			&lt;rich:pickList value="#{compraAction.listaLojasSelecionadas}"&gt;
				&lt;f:selectItems value="#{compraAction.listaSelectItemsLojas()}"/&gt;
			&lt;/rich:pickList&gt;
			<br />
[...]

Alguém sabe o que tem que fazer/alterar?

Alguém pode me ajudar?

Diogo_Jr, estou com o mesmo problema que você. A situação é bem semelhante, o meu relacionamento tbm é n:n. Estou pesquisando aki pra vê se acho algo. Se eu achar posto a solução. Se vc achar primeiro que eu, poste ai pra gente.

Se alguém puder nos ajudar, fique a vontade.
=D