Problemas com Classes relacionadas no JSF

17 respostas
espiaoweb2011

Olá, estou tendo um problema com JSF e gostaria de saber como solucionar isso…

A duvida é a seguinte…

Imagine a seguinte situação…

Tenho uma aplicação que utiliza JSF com JPA (Hibernate) e Mysql como DB,

Tenho duas Classes mapeadas no Hibernate : (segue ex das classes abaixo)

Aluno

int id; (pk)

String nome;

Turma turma_id; (fk = Turma.id)

Turma

int id;
String nome;


Tbm tenho dois ManageBeans : (segue abaixo os ex dos metodos utilizados)

TurmaBean

  • getTurmas() : ArrayList

AlunoBean

  • novoAluno() : String

E por fim tenho uma view que foi criada para salvar um novo aluno (segue abaixo o problema)

  • O problema é o seguinte, eu criei o formulario jsf para inserção de um novo aluno no banco de dados, so que acontece o seguinte erro: [color=darkred]Diz que 1 não pode ser convertido para Null[/color], algo assim. (no campo que se referencia ao atributo turma do aluno).

-Segue o trecho de codigo que tenho em minha view.


View novoAluno.xhtml

<h:form>

<h:outputLabel value="Nome" />
    <h:inputText value="#{alunoBean.aluno.nome}" />
    
    [color=red]<h:outputLabel value="Turma" />
    <h:selectOneMenu value="#{alunoBean.aluno.turma}">
        <f:selectItems value="#{turmaBean.turmas}" var="t" itemValue="#{t.id}" itemLabel="#{t.nome}" />
    </h:selectOneMenu>[/color]      

    <h:commandButton value="Salvar Aluno" action="#{alunoBean.novoAluno}" />

</h:form>


  • Imagino o seguinte, como o atributo turma, faz refencia a classe Turma, pode ter algo ai que não estou sabendo fazer, li algo sobre a criação de um converter, mais não sei como fazer neste caso.

#### Alguem sabe como resolvo isso, Obrigado ####

17 Respostas

Diego_Adriano

Tenta alterar essa parte

<h:inputText value="#{alunoBean.aluno.turma}" />

Para

<h:inputText value="#{alunoBean.aluno.turma_id}" />

O campo na view precisa ser igual o da sua Classe !
Abraços

espiaoweb2011

Diego Adriano:
Tenta alterar essa parte

<h:inputText value="#{alunoBean.aluno.turma}" />

Para

<h:inputText value="#{alunoBean.aluno.turma_id}" />

O campo na view precisa ser igual o da sua Classe !
Abraços

Olá Diego Adriano, o atributo turma na minha classe Aluno é somente turma e não turma_id, turma_id é somente no meu banco de dados, quando voce coloca tipo turma_id no nome do campo o Hibernate entende como chave (Fk) e remove o _id deixando somente turma na hora da importação o vice e versa.

Mesmo assim agradeço.

A

Opa, boa tarde.

Você poderia printar o stack completo ?

[]'s

Diego_Adriano

Amigo, o erro se dá por vc tentar exibir um valor “int” em um campo que espera uma String . Poste suas classes por favor …

espiaoweb2011

alex.brito:
Opa, boa tarde.

Você poderia printar o stack completo ?

[]'s

Não aprensenta rota nenhuma de erro, somente esta mensagem no browser (cliente):

[color=red]Erro de conversão ao definir o valor ‘1’ para ‘null Converter’. [/color]

espiaoweb2011

Segue minhas classes…

Aluno.java

package pojos;

import java.io.Serializable;
import javax.persistence.*;


/**
 * The persistent class for the alunos database table.
 * 
 */
@Entity
@Table(name="alunos")
public class Aluno implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(unique=true, nullable=false)
	private int id;

	@Column(nullable=false, length=45)
	private String nome;

	//bi-directional many-to-one association to Turma
    @ManyToOne
	@JoinColumn(name="turma_id", nullable=false)
	private Turma turma;

    public Aluno() {
    }

	public int getId() {
		return this.id;
	}

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

	public String getNome() {
		return this.nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Turma getTurma() {
		return this.turma;
	}

	public void setTurma(Turma turma) {
		this.turma = turma;
	}
	
}

Turma.java

package pojos;

import java.io.Serializable;
import javax.persistence.*;
import java.util.List;


/**
 * The persistent class for the turmas database table.
 * 
 */
@Entity
@Table(name="turmas")
public class Turma implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(unique=true, nullable=false)
	private int id;

	@Column(nullable=false, length=45)
	private String nome;

	//bi-directional many-to-one association to Aluno
	@OneToMany(mappedBy="turma")
	private List<Aluno> alunos;

    public Turma() {
    }

	public int getId() {
		return this.id;
	}

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

	public String getNome() {
		return this.nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public List<Aluno> getAlunos() {
		return this.alunos;
	}

	public void setAlunos(List<Aluno> alunos) {
		this.alunos = alunos;
	}
	
}

AlunoBean.java

package beans;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import pojos.Aluno;

public class AlunoBean {

	private EntityManagerFactory factory = Persistence
			.createEntityManagerFactory("CadastroAlunos");

	private Aluno aluno = new Aluno();

	public Aluno getAluno() {
		return aluno;
	}

	public void setAluno(Aluno aluno) {
		this.aluno = aluno;
	}

	public String salvaAluno() {

		try {

			EntityManager em = factory.createEntityManager();
			em.getTransaction().begin();

			em.persist(aluno);

			em.getTransaction().commit();
			em.close();

			return "sucesso";

		} catch (Exception e) {

			e.printStackTrace();
			return "erro";

		}

	}

}

TurmaBean.java

package beans;

import java.util.ArrayList;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import pojos.Turma;

public class TurmaBean {

	private EntityManagerFactory factory = Persistence
			.createEntityManagerFactory("CadastroAlunos");

	private Turma turma = new Turma();

	public Turma getTurma() {
		return turma;
	}

	public void setTurma(Turma turma) {
		this.turma = turma;
	}

	public ArrayList<Turma> getTurmas() {

		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();

		Query q = em.createQuery("select t from Turma t");

		@SuppressWarnings("unchecked")
		ArrayList<Turma> turmas = (ArrayList<Turma>) q.getResultList();

		em.getTransaction().commit();
		em.close();

		return turmas;
	}

}

novoAluno.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">


<h:form id="formulario">

	<h:panelGrid columns="3">

		<h:outputLabel value="Nome" />
		<h:inputText value="#{alunoBean.aluno.nome}" id="nome" label="Nome" />
		<h:message for="nome" />

		<h:outputLabel value="Turma" />
		<h:selectOneMenu value="#{alunoBean.aluno.turma}" id="turma"
			label="Turma">
			<f:selectItems value="#{turmaBean.turmas}" var="t"
				itemValue="#{t.id}" itemLabel="#{t.nome}" />
		</h:selectOneMenu>
		<h:message for="turma" />

		<h:commandButton value="Salvar Aluno" action="#{alunoBean.salvaAluno}" />

	</h:panelGrid>

</h:form>


</html>
Hebert_Coelho

Ou você aponta o valor da combo para o id da sua class. #{meuBean.minhaClasse.id} ou então você cria um Converter e passa a class direto na combo.

Nesse post eu mostro como criar um converter. JSF: Converter e Bean Auto Complete

Diego_Adriano

Bem, agora me lembrei desse problema .. resolvo dessa forma:

Class Cliente
@ManyToOne
	@JoinColumn(name="funcionario_id")
	private Funcionario professorID;
ClienteBean
private Long professorID;

public void adiciona(){
		System.out.println("CLIENTE ADD");
		
		ELContext elContext = FacesContext.getCurrentInstance().getELContext();
		this.entityManager = (EntityManager) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "entityManager");
		
		FuncionarioRepository funcionarioRepository = new FuncionarioRepository(this.entityManager);
		Funcionario Funcionario = funcionarioRepository.procura(this.professorID);
		
		this.cliente.setFuncionario(Funcionario);
Xhtml:
<h:outputLabel value="Instrutor : " for="cliente-instrutor" />
										<p:selectOneMenu id="cliente-instrutor" value="#{clienteBean.professorID}" required="true">
											
											<f:selectItems 
															value="#{funcionarioBean.funcionarios}"
															var="funcionarios"
															itemLabel="#{funcionarios.nome}"
															itemValue="#{funcionarios.id}"/>
											
											<p:message for="cliente-instrutor" styleClass="mensagem-erro"/>
										</p:selectOneMenu>
espiaoweb2011
Diego Adriano:
Bem, agora me lembrei desse problema .. resolvo dessa forma: Class Cliente
@ManyToOne
	@JoinColumn(name="funcionario_id")
	private Funcionario professorID;
ClienteBean
private Long professorID;

public void adiciona(){
		System.out.println("CLIENTE ADD");
		
		ELContext elContext = FacesContext.getCurrentInstance().getELContext();
		this.entityManager = (EntityManager) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "entityManager");
		
		FuncionarioRepository funcionarioRepository = new FuncionarioRepository(this.entityManager);
		Funcionario Funcionario = funcionarioRepository.procura(this.professorID);
		
		this.cliente.setFuncionario(Funcionario);
Xhtml:
<h:outputLabel value="Instrutor : " for="cliente-instrutor" />
										<p:selectOneMenu id="cliente-instrutor" value="#{clienteBean.professorID}" required="true">
											
											<f:selectItems 
															value="#{funcionarioBean.funcionarios}"
															var="funcionarios"
															itemLabel="#{funcionarios.nome}"
															itemValue="#{funcionarios.id}"/>
											
											<p:message for="cliente-instrutor" styleClass="mensagem-erro"/>
										</p:selectOneMenu>

Não percebi mundanças na logica comparando com as minhas classes, onde esta a chave de tudo ?

R

Meu caro,oq vc precisa é de um converter:
Da uma olhada nesses links:
http://www.rponte.com.br/2008/07/26/entity-converters-pra-da-e-vender/
http://www.rponte.com.br/2008/02/01/selectonemenu-converter-erro-de-validacao/

espiaoweb2011

jakefrog:
Ou você aponta o valor da combo para o id da sua class. #{meuBean.minhaClasse.id} ou então você cria um Converter e passa a class direto na combo.

Nesse post eu mostro como criar um converter. JSF: Converter e Bean Auto Complete

Olá amigo, ja tentei de toda maneira criar este converter, mais nenhum que se ajusta-se ao meu caso.

Analisando minhas classes abaixo, como teria que ficar a implementação deste converter ?

Segue minhas classes…

Aluno.java

package pojos;

import java.io.Serializable;
import javax.persistence.*;


/**
 * The persistent class for the alunos database table.
 * 
 */
@Entity
@Table(name="alunos")
public class Aluno implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(unique=true, nullable=false)
	private int id;

	@Column(nullable=false, length=45)
	private String nome;

	//bi-directional many-to-one association to Turma
    @ManyToOne
	@JoinColumn(name="turma_id", nullable=false)
	private Turma turma;

    public Aluno() {
    }

	public int getId() {
		return this.id;
	}

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

	public String getNome() {
		return this.nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Turma getTurma() {
		return this.turma;
	}

	public void setTurma(Turma turma) {
		this.turma = turma;
	}
	
}

Turma.java

package pojos;

import java.io.Serializable;
import javax.persistence.*;
import java.util.List;


/**
 * The persistent class for the turmas database table.
 * 
 */
@Entity
@Table(name="turmas")
public class Turma implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(unique=true, nullable=false)
	private int id;

	@Column(nullable=false, length=45)
	private String nome;

	//bi-directional many-to-one association to Aluno
	@OneToMany(mappedBy="turma")
	private List<Aluno> alunos;

    public Turma() {
    }

	public int getId() {
		return this.id;
	}

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

	public String getNome() {
		return this.nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public List<Aluno> getAlunos() {
		return this.alunos;
	}

	public void setAlunos(List<Aluno> alunos) {
		this.alunos = alunos;
	}
	
}

AlunoBean.java

package beans;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import pojos.Aluno;

public class AlunoBean {

	private EntityManagerFactory factory = Persistence
			.createEntityManagerFactory("CadastroAlunos");

	private Aluno aluno = new Aluno();

	public Aluno getAluno() {
		return aluno;
	}

	public void setAluno(Aluno aluno) {
		this.aluno = aluno;
	}

	public String salvaAluno() {

		try {

			EntityManager em = factory.createEntityManager();
			em.getTransaction().begin();

			em.persist(aluno);

			em.getTransaction().commit();
			em.close();

			return "sucesso";

		} catch (Exception e) {

			e.printStackTrace();
			return "erro";

		}

	}

}

TurmaBean.java

package beans;

import java.util.ArrayList;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import pojos.Turma;

public class TurmaBean {

	private EntityManagerFactory factory = Persistence
			.createEntityManagerFactory("CadastroAlunos");

	private Turma turma = new Turma();

	public Turma getTurma() {
		return turma;
	}

	public void setTurma(Turma turma) {
		this.turma = turma;
	}

	public ArrayList<Turma> getTurmas() {

		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();

		Query q = em.createQuery("select t from Turma t");

		@SuppressWarnings("unchecked")
		ArrayList<Turma> turmas = (ArrayList<Turma>) q.getResultList();

		em.getTransaction().commit();
		em.close();

		return turmas;
	}

}

novoAluno.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">


<h:form id="formulario">

	<h:panelGrid columns="3">

		<h:outputLabel value="Nome" />
		<h:inputText value="#{alunoBean.aluno.nome}" id="nome" label="Nome" />
		<h:message for="nome" />

		<h:outputLabel value="Turma" />
		<h:selectOneMenu value="#{alunoBean.aluno.turma}" id="turma"
			label="Turma">
			<f:selectItems value="#{turmaBean.turmas}" var="t"
				itemValue="#{t.id}" itemLabel="#{t.nome}" />
		</h:selectOneMenu>
		<h:message for="turma" />

		<h:commandButton value="Salvar Aluno" action="#{alunoBean.salvaAluno}" />

	</h:panelGrid>

</h:form>


</html>
Diego_Adriano

Mano … a diferença esta aqui … repare que passo o valor setado ao meu Bean então faço uma consulta pelo id e então insiro o valor no objeto Cliente:

<p:selectOneMenu id="cliente-instrutor" value="#{clienteBean.professorID}" > //xhtml

private Long professorID// Atributo que recebera no Bean

//CRIO UM OBJ DE FUNCIONARIO E CONSULTO PELO ID RECEBIDO DA VIEW
Funcionario Funcionario = funcionarioRepository.procura(this.professorID);   

//POR FIM ATRIBUO O OBJETO FUNCIONARIO AO CLIENTE
 this.cliente.setFuncionario(Funcionario);

Antes de fazer dessa forma tentava fazer como vc, passar o valor diretamente mas nunca fncionava e isso foi a minha solução.

R

espiao e Diego,

dêem uma olhada nesse link do converter que eu passei,é um converter genérico(ou seja,n precisa criar um pra cada entidade) e evita ter que procurar o objeto pelo id.

Diego_Adriano

Opa Rafael … vou ler sim cara …
Vlw

espiaoweb2011

raf4ever:
espiao e Diego,

dêem uma olhada nesse link do converter que eu passei,é um converter genérico(ou seja,n precisa criar um pra cada entidade) e evita ter que procurar o objeto pelo id.

Olá Rafael, ja li seus posts sim, tentei fazer a implementação do converte mais não rolou, triplicou a rota de erros.

Penso desta maneira, um framework foi feito para facilitar nossas vidas, correto ?

Sou iniciante com JSF, mais ja venho de outros frameworks Web (ex Django e Rails), e nestes frameworks eu não preciso de mais 3 ou 5 classes para eu salvar objetos relacionados no DB.

Analisando minha situação seria simples de explicar teoricamente o que quero fazer, quero salvar um objeto Aluno que possui uma turma do tipo Turma no banco, este aluno tem um nome do tipo String, então passo o nome(string) e a turma(Turma), ai me aparece um erro de conversão, que para resolver ele tenho que escrever mais 3 ou 5 classes. Fica meio foda de imaginar na pratica o que esta acontecendo (motivo do erro).

Agradeço pela ajuda sua e dos outros usuários que estão respondendo este topico que estão apresentando varias ideias de como resolver este problema, mais so queria saber a maneira correta de implementar este converter de acordo com minhas classes que ja passei nos posts acima.

R

espiaoweb2011:
raf4ever:
espiao e Diego,

dêem uma olhada nesse link do converter que eu passei,é um converter genérico(ou seja,n precisa criar um pra cada entidade) e evita ter que procurar o objeto pelo id.

Olá Rafael, ja li seus posts sim, tentei fazer a implementação do converte mais não rolou, triplicou a rota de erros.

Penso desta maneira, um framework foi feito para facilitar nossas vidas, correto ?

Sou iniciante com JSF, mais ja venho de outros frameworks Web (ex Django e Rails), e nestes frameworks eu não preciso de mais 3 ou 5 classes para eu salvar objetos relacionados no DB.

Analisando minha situação seria simples de explicar teoricamente o que quero fazer, quero salvar um objeto Aluno que possui uma turma do tipo Turma no banco, este aluno tem um nome do tipo String, então passo o nome(string) e a turma(Turma), ai me aparece um erro de conversão, que para resolver ele tenho que escrever mais 3 ou 5 classes. Fica meio foda de imaginar na pratica o que esta acontecendo (motivo do erro).

Agradeço pela ajuda sua e dos outros usuários que estão respondendo este topico que estão apresentando varias ideias de como resolver este problema, mais so queria saber a maneira correta de implementar este converter de acordo com minhas classes que ja passei nos posts acima.

Qual o erro que deu?

espiaoweb2011

raf4ever:
espiaoweb2011:
raf4ever:
espiao e Diego,

dêem uma olhada nesse link do converter que eu passei,é um converter genérico(ou seja,n precisa criar um pra cada entidade) e evita ter que procurar o objeto pelo id.

Olá Rafael, ja li seus posts sim, tentei fazer a implementação do converte mais não rolou, triplicou a rota de erros.

Penso desta maneira, um framework foi feito para facilitar nossas vidas, correto ?

Sou iniciante com JSF, mais ja venho de outros frameworks Web (ex Django e Rails), e nestes frameworks eu não preciso de mais 3 ou 5 classes para eu salvar objetos relacionados no DB.

Analisando minha situação seria simples de explicar teoricamente o que quero fazer, quero salvar um objeto Aluno que possui uma turma do tipo Turma no banco, este aluno tem um nome do tipo String, então passo o nome(string) e a turma(Turma), ai me aparece um erro de conversão, que para resolver ele tenho que escrever mais 3 ou 5 classes. Fica meio foda de imaginar na pratica o que esta acontecendo (motivo do erro).

Agradeço pela ajuda sua e dos outros usuários que estão respondendo este topico que estão apresentando varias ideias de como resolver este problema, mais so queria saber a maneira correta de implementar este converter de acordo com minhas classes que ja passei nos posts acima.

Qual o erro que deu?

De acordo com seu post, criei a interface BaseEntity e o converter generico, no xhtml(view) apontei o converter e deu este erro:

javax.servlet.ServletException: pojos.Turma cannot be cast to converters.BaseEntity
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:521)
Criado 10 de novembro de 2011
Ultima resposta 10 de nov. de 2011
Respostas 17
Participantes 5