Erro de Validação de objetos com SelectOneMenu - JSF 2 + Primefaces + CDI

Olá,

Estou desenvolvendo um projeto envolvendo JSF 2 + Primefaces 3.3 + Hibernate 4 + CDI, mas quebrando muito a cabeça no momento tentando resolver um problema de validação de um componente SelectOneMenu, onde é exibida a mensagem [size=12]Erro de validação: o valor não é válido[/size].

Pensando na questão da validação, implementei o equals e hashcode no objeto na classe do objeto, mas sem sucesso, sendo que também o conversor retorna um objeto pelo DAO.

Alguém passou por um caso semelhante e conseguiu resolver??

Segue códigos:

Entity


@Entity
public class Area implements Serializable {

	private static final long serialVersionUID = 2540606008938164732L;

	@Id
	@GeneratedValue
	private Long id;
	
	@Column(length=30, nullable=false)
	private String nome;

	@Column(length=50, nullable=false)
	private String gerente;

	@OneToMany(cascade=CascadeType.PERSIST, mappedBy="area")
	private List<Demanda> demandas = new ArrayList<Demanda>();

        //GETTERS E SETTERS
        //HASHCODE E EQUALS

}

@Entity
public class Demanda implements Serializable{

	private static final long serialVersionUID = 7053604534977914318L;

	@Id
	@GeneratedValue
	private Long id;
	
	@Temporal(TemporalType.TIMESTAMP)
	private Date dataInclusao;
	
	@Temporal(TemporalType.DATE)
	private Date prazo1 = new Date();
	
	@Temporal(TemporalType.DATE)
	private Date prazo2;
	
	@Column(length=100, nullable=false)
	private String providencia;

	@Column(length=255, nullable=false)
	private String anotacao;
	
	@Enumerated(EnumType.STRING)
	private String status = "A";
	
	@ManyToOne
	private Area area;
	
        //GETTERS E SETTERS

Converter

[code]

@FacesConverter(forClass=Area.class)
public class AreaConverter implements Converter{

private AreaDAO areaDao = new AreaDAO();

@Override
public Object getAsObject(FacesContext ctx, UIComponent comp, String value) {
	if(value != null) {
		Long id = Long.valueOf(value);
		return areaDao.buscaPorId(id);
	}else {
		return null;
	}
}

@Override
public String getAsString(FacesContext ctx, UIComponent comp, Object value) {
	return String.valueOf(((Area) value).getId());
}

}[/code]

Bean


@Model
public class AreaBean implements Serializable{
	
	private static final long serialVersionUID = 1L;

	@Inject
	private Demanda demanda;
	
	@Inject
	private DAO<Area> areaDAO;	
	
	@Produces
	@SessionScoped
	@Named("areas")
	private List<Area> getAreas(){
		return areaDAO.listaTodos();
	}

        //GETTERS E SETTERS
}

XHTML


	 				<h:outputLabel for="area" value="Área"/>
					<p:selectOneMenu id="area" value="#{areaBean.demanda.area}" effect="fade">
						<f:selectItems value="#{areas}" var="area" itemValue="#{area}" itemLabel="#{area.nome}"/>
					</p:selectOneMenu>

Erro

sourceId=j_idt6:area[severity=(ERROR 2), summary=(j_idt6:area: Erro de validação: o valor não é válido), detail=(j_idt6:area: Erro de validação: o valor não é válido)]

Faltou colocar <f:converter converterId=“SEU_CONVERTER”/> no seu converter.

Qualquer outra dúvida, leia aqui: http://uaihebert.com/?p=35 .

Deu o mesmo erro.

Como havia o forClass no atributo do converter, o mesmo já estava sendo chamado.

Qual o valor está chegando no seu converter?

O value chega em String, com o ID da área (objeto).

O estranho é que o equals dá false, não entendo.

Marcos,

Você já resolveu isto?

Olha só, não vi se suas classes de entidade consideram isto, mas embora isto não esteja escrito explicitamente, você precisa implementar os métodos equals e hashCode nelas. Isto é uma recomendação da especificação JPA e existe um artigo sobre o Hibernate (não lembro onde, mas faz parte da documentação dele) que explica o porque isto é crucial.

Já tive problemas de validação usando esses converters no p:selectOneMenu e a implementação destes métodos nas classes de entidades resolveram o problema.

Espero que isto ajude, ainda que tarde…

Abraço,
Paulo R.

Paulo,

Consegui identificar o problema. Eu já havia implementado o equals e o hashcode no objeto, o erro de validação ocorria por causa do mappedBy, o que fazia com que o objeto fosse checado pelo equals da classe do objeto que estava relacionado pelo mappedBy. Ele era checado então pelo objeto relacionado e não era validado nunca, porque o id sempre retornava diferente da lista criada no selectOneMenu.

Removi então o mappedBy e funcionou perfeitamente.

Agradeço a atenção.

Caraca, calma aí.

O mappedBy do hibernate estava atrapalhando na validação do JSF? :shock: :shock: :shock:

Alguem pode confirmar isso? o Hibernate influenciou no converter?
tenho um problema parecido

meu problema é exatamente esse:


não sei se é problema de validator, ou do JSF, ou do primefaces, ou de algum outro lugar que nem sei ainda!!! :slight_smile:

Agradeço qquer ajuda

[quote=paulorf1971]Marcos,

Você já resolveu isto?

Olha só, não vi se suas classes de entidade consideram isto, mas embora isto não esteja escrito explicitamente, você precisa implementar os métodos equals e hashCode nelas. Isto é uma recomendação da especificação JPA e existe um artigo sobre o Hibernate (não lembro onde, mas faz parte da documentação dele) que explica o porque isto é crucial.

Já tive problemas de validação usando esses converters no p:selectOneMenu e a implementação destes métodos nas classes de entidades resolveram o problema.

Espero que isto ajude, ainda que tarde…

Abraço,
Paulo R.[/quote]

Isso resolveu para mim.

Muito Obrigado!