[RESOLVIDO]Pegar objeto no selectOneMenu primefaces
12 respostas
Benjamin10
Boa noite pessoal, tenho um selectOneMenu que contem os estados cadastrados em um dialog que é para gravar uma nova cidade e indicar seu estado.
Mas quando mando gravar ele não pega o valor do estado no selectOneMenu. Abaixo os códigos que fiz.
Select One Menu
<p:dialogheader="Informe o nome do estado"widgetVar="dlgInserir"width="500"height="300"showEffect="clip">Nome:<p:inputTextvalue="#{cidadeBean.cidade.nome}"required="true"requiredMessage="O campo nome esta vazio"/>Estado:<p:selectOneMenuid="selecionaEstado"value="#{cidadeBean.estadoSelecionado}"converter="CidadeConverter"><f:selectItemitemLabel="Selecione o estado"/><f:selectItemsvalue="#{cidadeBean.estados}"var="estado"itemLabel="#{estado.nome}"itemValue="#{estado.idEstado}"/></p:selectOneMenu><p:commandButtonvalue="Confirmar"icon="ui-icon-check"action="#{cidadeBean.gravar()}"ajax="false"/><p:commandButtonvalue="Limpar"type="reset"ajax="false"/></p:dialog>
Método gravar no Bean
publicvoidgravar()throwsDaoException{this.estadoSelecionado=newEstado();this.cidade.setEstado(estadoSelecionado);dao.salvarOuAlterar(cidade);addMessageSucesso("Gravado Com Sucesso");cidade=null;}
E as Classes Estado e Cidade
@EntitypublicclassEstadoimplementsSerializable{/** * */privatestaticfinallongserialVersionUID=1L;@Id@GeneratedValue(strategy=GenerationType.AUTO)privateIntegeridEstado;@Column(length=50,nullable=false,name="nome_estado")privateStringnome;@OneToMany(fetch=FetchType.LAZY,mappedBy="estado")privateSet<Cidade>cidades=newHashSet<Cidade>();publicStringgetNome(){returnnome;}publicvoidsetNome(Stringnome){this.nome=nome;}publicIntegergetIdEstado(){returnidEstado;}publicvoidsetId(Integerid){this.idEstado=id;}publicSet<Cidade>getCidades(){returnCollections.unmodifiableSet(this.cidades);}publicvoidaddCidade(Cidadecidade){if(cidade==null){thrownewIllegalArgumentException("Cidade não pode ser null");}this.cidades.add(cidade);cidade.setEstado(this);}publicbooleanremoveCidade(Cidadecidade){if(cidade==null){thrownewIllegalArgumentException("Cidade não pode ser null");}if(this.cidades.remove(cidade)){cidade.setEstado(null);returntrue;}returnfalse;}}@EntitypublicclassCidadeimplementsSerializable{/** * */privatestaticfinallongserialVersionUID=1L;@Id@GeneratedValue(strategy=GenerationType.AUTO)privateIntegeridCidade;@Column(length=50,name="nome_cidade")privateStringnome;@ManyToOne(fetch=FetchType.LAZY,optional=false)@JoinColumn(name="estado",referencedColumnName="idestado")privateEstadoestado=newEstado();publicStringgetNome(){returnnome;}publicvoidsetNome(Stringnome){this.nome=nome;}publicIntegergetIdCidade(){returnidCidade;}publicEstadogetEstado(){returnestado;}publicvoidsetEstado(Estadoestado){this.estado=estado;}}
Clássico problema de converter, olhe este post de um tempo atrás que você será feliz kkkkkkkkkk
Benjamin10
Pessoal troquei o converter para um genérico, porém agora ele dá erro de estado null, como a coluna estado da tabela cidade é uma fk, ele não deixa gravar como null.
publicclassEntityConverterimplementsConverter{publicObjectgetAsObject(FacesContextctx,UIComponentcomponent,Stringvalue){if(value!=null){returncomponent.getAttributes().get(value);}returnnull;}publicStringgetAsString(FacesContextctx,UIComponentcomponent,Objectobj){if(obj!=null&&!"".equals(obj)){Stringid;try{id=this.getId(getClazz(ctx,component),obj);if(id==null){id="";}id=id.trim();component.getAttributes().put(id,getClazz(ctx,component).cast(obj));returnid;}catch(SecurityExceptione){e.printStackTrace();// seu log aqui }catch(IllegalArgumentExceptione){e.printStackTrace();// seu log aqui }catch(NoSuchFieldExceptione){e.printStackTrace();// seu log aqui }catch(IllegalAccessExceptione){e.printStackTrace();// seu log aqui }}returnnull;}/** * Obtém, via expression language, a classe do objeto. * * @param FacesContext facesContext * * @param UICompoment compoment * * @return Class<?> */privateClass<?>getClazz(FacesContextfacesContext,UIComponentcomponent){returncomponent.getValueExpression("value").getType(facesContext.getELContext());}/** * Retorna a representação em String do retorno do método anotado com @Id ou @EmbeddedId do objeto. * * @param Class<?> clazz * * @return String */publicStringgetId(Class<?>clazz,Objectobj)throwsSecurityException,NoSuchFieldException,IllegalArgumentException,IllegalAccessException{List<Class<?>>hierarquiaDeClasses=this.getHierarquiaDeClasses(clazz);for(Class<?>classeDaHierarquia:hierarquiaDeClasses){for(Fieldfield:classeDaHierarquia.getDeclaredFields()){if((field.getAnnotation(Id.class))!=null||field.getAnnotation(EmbeddedId.class)!=null){FieldprivateField=classeDaHierarquia.getDeclaredField(field.getName());privateField.setAccessible(true);if(privateField.get(clazz.cast(obj))!=null){return(String)field.getType().cast(privateField.get(clazz.cast(obj))).toString();}}}}returnnull;}/** * Retorna uma lista com a hierarquia de classes, sem considerar a classe Object.class * * @param Class<?> clazz * * @return List<Class<?>> clazz */publicList<Class<?>>getHierarquiaDeClasses(Class<?>clazz){List<Class<?>>hierarquiaDeClasses=newArrayList<Class<?>>();Class<?>classeNaHierarquia=clazz;while(classeNaHierarquia!=Object.class){hierarquiaDeClasses.add(classeNaHierarquia);classeNaHierarquia=classeNaHierarquia.getSuperclass();}returnhierarquiaDeClasses;}}
Alguém mais poderia me ajudar,!!!
A
andre.froes
Como eu te passei no link Benjamin10, para selects, você não precisa de um converter, você precisa somente passar a lista de collection carregada:
este é o código no post que eu te passei como link, é específico para carregar um select:
publicCollection<SelectItem>getCarregarSelect(){Collection<SelectItem>lst=newArrayList<SelectItem>();lst.add(newSelectItem(null,"Selecione o estado"));//Primeiro item do select List<Estado>lista=**carregarlistacomosestados**;//query que busca os valores do bdfor(inti=0;i<lista.size();i++){lst.add(newSelectItem(lista.get(i).getEstadoId(),lista.get(i).getNomeEstado()));//new SelectItem(valor, rótulo);//no exemplo acima, o estadoId() é o valor, e o nomeEstado() é o rótulo, é tudo carregado aqui}returnlst;}
não precisa do converter, o valor você converte/valida ao recuperá-lo
Benjamin10
Obrigado pela dica, listou os dados certinho aqui, ele continua dando pedindo pra converter o dado?/
O que eu quero é pegar o objeto selecionado no SelectOneMenu com se nome e id, e no bean setar esse objeto pego no setEstado da classe Cidade. Pois tenho um relacionamento entre as classes como coloquei acima.
Então quando eu coloco no bean
cidade.setEstado(estadoSelecionado);
O estado esta vindo null !!
tem alguma forma de resolver isso?/
A
andre.froes
Faça um teste, crie uma nova variável no teu mb, uma String mesmo, atrele o valor no seu select, e no momento que você executar a operação, debugue o sistema e veja se o valor está vindo ou se preferir, apenas de um print no valor dessa string, veja se o valor segue null.
Benjamin10
Fiz a variavél String que você falou, dai ele retorna o id do estado.
A
andre.froes
Beleza, estamos indo no caminho certo, aqui você já pode solucionar o teu problema.
O que aconteceria se você encontrasse o objeto agora?
é que meu nome_estado é notnull, e ele ta pedindo pra colocar o nome também.
É assim mesmo ou tem algo de errado com meus relacionamentos entre as entidades?/
Benjamin10
Caro andre.froes solucionei o problema, tirei o cascade da classe Cidade e funcionou belezinha rsrs
Obrigado pela grande ajuda,
abraços
A
andre.froes
Cara, um ID é atrelado a um nome somente correto? Não existem estados com o mesmo nome, somente cidades, então não tem porque ter o atributo nome_estado obrigatório pq já é tudo predefinido, esses valores não irão mutar em momento algum. Mas bem, todos os valores que você está trabalhando no sistema agora são conhecidos, você só tem que saber como jogar com eles, para localizar um estado, dependendo de como está a sua estrutura de tabela, basta somente que você tenha em mãos o ID dele correto? Pelo ID você fará o hook no objeto inteiro, o que nada mais seria um select “SELECT * FROM estado WHERE ID=#”, com isso você tem o seu objeto, agora, se você está com erro ao buscar este objeto, os quinhentos são outros, tu tem que revisar seu DB e tuas entidades.