[RESOLVIDO] recuperar lista vraptor3

16 respostas
salmaox

boa tarde!

Possuo um form com dois combos:
1 - Grupo
2 - Operadores

Quando seleciono o combo grupos ele traz o combo operadores preenchido dando um submit através de uma função javascript, no entanto o campo grupo não mantém a opção escolhida.
Segue meu código:

novo.jsp

<select name="operador.grupo.idgrupo" onChange="document.getElementById('form').action='<c:url value="/gerente/novo"/>'; document.getElementById('form').target='_self'; document.getElementById('form').submit();" />
    	<option value="select">Selecione</option>
    	<c:forEach var="g" items="${lista_grupo}">
    	<c:if test="${operador.grupo.idgrupo == g.idgrupo}">">
    		<option selected="selected" value="<c:out value="${g.idgrupo}" />"><c:out value="${g.nome}" /></option>	
    	</c:if>
    	<c:if test="${operador.grupo.idgrupo != g.idgrupo}">">
    		<option value="<c:out value="${g.idgrupo}" />"><c:out value="${g.nome}" /></option>
    	</c:if>
    	</c:forEach>
    </select>
</td>
  </tr>
   <tr>
   <td width="15%">Operador:</td>
    <td width="85%">
    <select name="operador.idoperador">
    	<c:forEach var="op" items="${lista_operador}">
    		<option value="<c:out value="${op.idoperador}" />"><c:out value="${op.nome}" /></option>
    	</c:forEach>
    </select>
    </td>
  </tr>

Classe GerenteController

public List<Grupo> carregaListaGrupo(){
		List<Grupo> lista_grupo = gdao.listaTudo();
		result.include("lista_grupo",lista_grupo);
		return lista_grupo;		
	}

    @Get
	@Path("/novo")
	public void novo(){
		carregaListaGrupo();
	}
	
	@Post
	@Path("/novo")
	public void novo(Operador operador){
		carregaListaGrupo();
		carregaListaOperador(operador);
	}

Obs: Qnd dou o submit na página ele chama o método @Post “novo” mas parece que não executa o método carregaListaGrupo(); …

Obrigado
Abs

16 Respostas

Rafael_Guerreiro

Ainda não consegui entender por que o método carregaListaGrupo retorna uma List, acho que nesse caso ele funciona bem sendo void.

Você debugou e ele não entra no método? Ou o result não coloca a list na variável? Ou a lista está vindo vazia?

salmaox

Rafael,

Ele tem q retornar uma lista pra preecher o combo na view e de fato ele preeche. Mas ele não entra nesse IF
<c:if test="${operador.grupo.idgrupo == g.idgrupo}">">  
            <option selected="selected" value="<c:out value="${g.idgrupo}" />"><c:out value="${g.nome}" /></option>   
        </c:if>

E dessa forma o combo não mantém o grupo selecionado ao listar o combo dos operadores. É como se o “operador.grupo.idgrupo” não estivesse retornando nada…

Rafael_Guerreiro

Ele já está populando a lista na view quando vc dá o result.include(“lista_grupo”,lista_grupo); dentro do método, não há necessidade de retornar a lista o método pode ser void.

Se ele não entra no IF é porque ele não passou no teste :smiley:

Esse é o problema da JSP, não da para debugar, faz assim:

Operador = ${operador.grupo.idgrupo}<br />G: ${g.idgrupo} &lt;!-- antes de entrar no if, mostra os valores na tela mesmo --&gt; &lt;c:if test="${operador.grupo.idgrupo == g.idgrupo}"&gt;&quot;&gt; &lt;option selected="selected" value="&lt;c:out value="${g.idgrupo}" /&gt;&quot;&gt;&lt;c:out value="${g.nome}" /&gt;&lt;/option&gt; &lt;/c:if&gt;

Acho que dessa forma você consegue descobrir o que está acontecendo.

Uma perguntinha, qual a finalidade desse IF??

salmaox

Você tem razão Rafael, não precisa mesmo do método ser List já que o result envia pra view…Alterei o método pra void, obrigado. A idéia do IF é comparar os elementos da lista(combo do grupo) com o valor do combo(grupo) na hora do refresh da página.

Por exemplo: qnd eu selecionar um grupo no combo ele dá um submit, faz uma consulta no banco e traz no combo de baixo, todos os operadores referentes àquele grupo.

Estou com um probleminha no minha string sql se puder me ajudar…Acho q isso resolveria meu problema.

public List<Operador> listaOperadorPorGrupo(Operador operador){
		String sql = "FROM Operador o INNER JOIN Grupo g ON (o.id_grupo = g.id_grupo) where o.id_grupo = "+operador.getGrupo().getIdgrupo()+"";
		Query q = this.session.createQuery(sql);
		List lista = q.list();
		return lista;
	}

ele dá o seguinte erro:

org.hibernate.hql.ast.QuerySyntaxException: unexpected token: FROM near line 1, column 8 [select FROM br.org.cemaden.bean.Operador o INNER JOIN Grupo g ON (o.id_grupo = g.id_grupo) where o.id_grupo = 2]

Obrigado

Rafael_Guerreiro

Por que você não trabalha com Criteria? Acho bem mais fácil e não dá erro de sintaxe SQL.

Acho que ao invés de trazer a lista TODA e verificar se o item faz parte do grupo, vc deveria receber o grupo no submit e trazer somente a lista daquele grupo.
Assim a requisição ao banco de dados e a hora de popular a tela ficam mais rápidos.

Me mostra como estão as classes Operador e Grupo.

salmaox

Rafael, desculpe a demora na resposta. Precisei me ausentar do trabalho…

Eu tentei com o Criteria, mas apanhei tanto que desisti…

segue minhas classes modelo e DAO com o criteria…

@Entity
@Table(name="grupo")
public class Grupo {
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="id_grupo")
	private int idgrupo;
	
	@Column(name="nome", length=60)
	@NotNull
	private String nome;
	
	@OneToMany(mappedBy="grupo", fetch = FetchType.LAZY)
	@Cascade(CascadeType.ALL)
	private Collection<Gerente> gerente;
	
	public Collection<Gerente> getGerente() {
		return gerente;
	}
	public void setGerente(Collection<Gerente> gerente) {
		this.gerente = gerente;
	}
	public int getIdgrupo() {
		return idgrupo;
	}
	public void setIdgrupo(int idgrupo) {
		this.idgrupo = idgrupo;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
}
@Entity
@Table(name="operador")
public class Operador {
	
	@Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "id_operador") 
    private int idoperador;
	
	@ManyToOne
	@JoinColumn(name="id_grupo")
	private Grupo grupo;
	
	@Column(name="nome", length=60)
	@NotNull
	private String nome;
	
	@Column(name="email", length=60)
	@NotNull
	private String email;
	
	@Column(name="ramal", length=4)
	@Null
	private String ramal;
	
	@Column(name="telefone", length=14)
	@Null
	private String telefone;
	
	@Column(name="celular", length=14)
	@Null
	private String celular;
	
	@OneToMany(mappedBy="operador", fetch = FetchType.LAZY)
	@Cascade(CascadeType.ALL)
	private Collection<Gerente> gerente;
	
	public int getIdoperador() {
		return idoperador;
	}
	public void setIdoperador(int idoperador) {
		this.idoperador = idoperador;
	}
	public Grupo getGrupo() {
		return grupo;
	}
	public void setGrupo(Grupo grupo) {
		this.grupo = grupo;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getRamal() {
		return ramal;
	}
	public void setRamal(String ramal) {
		this.ramal = ramal;
	}
	public String getTelefone() {
		return telefone;
	}
	public void setTelefone(String telefone) {
		this.telefone = telefone;
	}
	public String getCelular() {
		return celular;
	}
	public void setCelular(String celular) {
		this.celular = celular;
	}
	public void setGerente(Collection<Gerente> gerente) {
		this.gerente = gerente;
	}
	public Collection<Gerente> getGerente() {
		return gerente;
	}
	
}
@Entity
public class Gerente {
	
	@Id
	@NotNull
	@GeneratedValue(strategy=GenerationType.AUTO)
	private int id_gerente;
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="id_operador", insertable=true, updatable=true)
	@Fetch(FetchMode.JOIN)
	private Operador operador;
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="id_grupo", insertable=true, updatable=true)
	@Fetch(FetchMode.JOIN)
	private Grupo grupo;
	
	@Column(name="senha")
	@NotNull
	private String senha;
	
	public int getId_gerente() {
		return id_gerente;
	}
	public void setId_gerente(int id_gerente) {
		this.id_gerente = id_gerente;
	}
	public Operador getOperador() {
		return operador;
	}
	public void setOperador(Operador operador) {
		this.operador = operador;
	}
	public Grupo getGrupo() {
		return grupo;
	}
	public void setGrupo(Grupo grupo) {
		this.grupo = grupo;
	}
	public String getSenha() {
		return senha;
	}
	public void setSenha(String senha) {
		this.senha = senha;
	}
}

Obrigado

Rafael_Guerreiro

Me responde só uma dúvida: é o Gerente que TEM um Operador e um Operador que TEM um grupo?

Com o Criteria fica simples, lembrando que você não precisa fazer Join Column pq o Hibernate ja vai fazer para vc.

Ve se não seria isso:

public List&lt;Operador&gt; listaOperadorPorGrupo(Operador operador){  
        //String sql = "FROM Operador o INNER JOIN Grupo g ON (o.id_grupo = g.id_grupo) where o.id_grupo = "+operador.getGrupo().getIdgrupo()+"";  
        //Query q = this.session.createQuery(sql);  
        //List lista = q.list();  
        //return lista;  

        return this.session.createCriteria(Operador.class)
			.add(Restrictions.eq("id_grupo", operador.getGrupo().getIdgrupo()))
			.list();
    }
salmaox

Isso mesmo, e na tabela gerente tem uma chave estrangeira de idoperador,idgrupo

CREATE TABLE “public”.“grupo” (

“id_grupo” INTEGER NOT NULL,

“nome” VARCHAR(60),

CONSTRAINT “grupo_pkey” PRIMARY KEY(“id_grupo”)

) WITHOUT OIDS;
CREATE TABLE “public”.“operador” (

“id_operador” INTEGER NOT NULL,

“celular” VARCHAR(14),

“email” VARCHAR(60),

“nome” VARCHAR(60),

“ramal” VARCHAR(4),

“telefone” VARCHAR(14),

“id_grupo” INTEGER,

CONSTRAINT “operador_pkey” PRIMARY KEY(“id_operador”),

CONSTRAINT “fke229ec94eb9d8aef” FOREIGN KEY (“id_grupo”)

REFERENCES “public”.“grupo”(“id_grupo”)

ON DELETE NO ACTION

ON UPDATE NO ACTION

NOT DEFERRABLE

) WITHOUT OIDS;
CREATE TABLE “public”.“gerente” (

“id_gerente” INTEGER NOT NULL,

“senha” VARCHAR(255),

“id_grupo” INTEGER,

“id_operador” INTEGER,

CONSTRAINT “gerente_pkey” PRIMARY KEY(“id_gerente”),

CONSTRAINT “fk5ea9f20e467855eb” FOREIGN KEY (“id_operador”)

REFERENCES “public”.“operador”(“id_operador”)

ON DELETE NO ACTION

ON UPDATE NO ACTION

NOT DEFERRABLE,

CONSTRAINT “fk5ea9f20eeb9d8aef” FOREIGN KEY (“id_grupo”)

REFERENCES “public”.“grupo”(“id_grupo”)

ON DELETE NO ACTION

ON UPDATE NO ACTION

NOT DEFERRABLE

) WITHOUT OIDS;

Esse criteria eu ja tentei antes…tentei novamente mas dá esse erro: org.hibernate.QueryException: could not resolve property: idgrupo of: br.org.cemaden.bean.Operador

salmaox

Rafael,

Tentei dessa forma tb

@SuppressWarnings("unchecked")
	public List<Operador> listaOperadorPorGrupo(Operador idgrupo){
		System.out.println("idDAO: "+idgrupo.getGrupo().getIdgrupo());
		Criteria criteria = this.session.createCriteria(Operador.class);
		criteria.createAlias("grupo", "Grupo", Criteria.INNER_JOIN);
		criteria.addOrder(Order.asc("idoperador"));
		criteria.add(Restrictions.eq("grupo", idgrupo));
		List<Operador> lista = criteria.list();
		return lista;	
	}

mas tá dando essa exception: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of br.org.cemaden.bean.Grupo.idgrupo

Rafael_Guerreiro

Esse erro é por que o parametro da propriedade está com nome errado.

Por que você não segue o padrão java de camelCase?

Ve se assim resolve (eu tinha errado o nome das variáveis e coloquei um Alias):

public List&lt;Operador&gt; listaOperadorPorGrupo(Operador operador){    
        //String sql = "FROM Operador o INNER JOIN Grupo g ON (o.id_grupo = g.id_grupo) where o.id_grupo = "+operador.getGrupo().getIdgrupo()+"";    
        //Query q = this.session.createQuery(sql);    
        //List lista = q.list();    
        //return lista;    
  
        return this.session
				.createCriteria(Operador.class)
				.createAlias("grupo", "grupo")
				.add(Restrictions.eq("grupo.idgrupo", operador.getGrupo()
						.getIdgrupo())).list(); 
    }
salmaox

agora deu certo :slight_smile: mas ele não entra nesse primeiro IF e não mantém a opção selecionada, eu preciso que ele mantenha o combo selecionado para fazer o cadastro do gerente…

<select name="operador.grupo.idgrupo" onChange="document.getElementById('form').action='<c:url value="/gerente/novo"/>'; document.getElementById('form').target='_self'; document.getElementById('form').submit();" />
    	<option value="select">Selecione</option>
    	<c:forEach var="g" items="${lista_grupo}">
    	<c:if test="${operador.grupo.idgrupo == g.idgrupo}">">
    		<option selected="selected" value="<c:out value="${g.idgrupo}" />"><c:out value="${g.nome}" /></option>	
    	</c:if>
    	<c:if test="${operador.grupo.idgrupo != g.idgrupo}">">
    		<option value="<c:out value="${g.idgrupo}" />"><c:out value="${g.nome}" /></option>
    	</c:if>
    	</c:forEach>
    </select>
Rafael_Guerreiro

Você fez o teste vendo quais valores ele mostra?

Assim acho que fica mais fácil de você encontrar o erro.

Operador = ${operador.grupo.idgrupo}<br />G: ${g.idgrupo}  
&lt;!-- antes de entrar no if, mostra os valores na tela mesmo --&gt;  
&lt;c:if test="${operador.grupo.idgrupo == g.idgrupo}"&gt;"&gt;      
            &lt;option selected="selected" value="&lt;c:out value="${g.idgrupo}" /&gt;"&gt;&lt;c:out value="${g.nome}" /&gt;&lt;/option&gt;       
        &lt;/c:if&gt;
salmaox

variável ${operador.grupo.idgrupo} traz qnd dá o submit pelo combo na primeira vez…senão nem carregava o método listaOperadorPorGrupo onde é passado o idgrupo por parâmetro. Só que após esse submit ela parece que fica null…

Rafael_Guerreiro

Então, quando você executar o método listaOperadorPorGrupo você deve dar um result.include e incluir a variável de novo. Essa variável só é incluida automaticamente quando ela for SessionScoped, mas ai ela será incluida em TODAS as requisições (mesmo as que não tiverem nada a ver).

salmaox

Isso mesmo Rafael consegui :slight_smile: Muito obrigado pela ajuda e paciência. Vlw mesmo…

Fiz dessa forma:

@Post
	@Path("/novo")
	public void novo(Operador operador){
		result.include("idgrupo",operador.getGrupo().getIdgrupo());
		carregaListaGrupo();
		carregaListaOperador(operador);
	}
<select name="operador.grupo.idgrupo" onChange="document.getElementById('form').action='<c:url value="/gerente/novo"/>'; document.getElementById('form').target='_self'; document.getElementById('form').submit();" />
    	<option value="select">Selecione</option>
    	<c:forEach var="g" items="${lista_grupo}">
    	<c:if test="${idgrupo == g.idgrupo}">">
    		<option selected="selected" value="<c:out value="${g.idgrupo}" />"><c:out value="${g.nome}" /></option>	
    	</c:if>
    	<c:if test="${idgrupo != g.idgrupo}">">
    		<option value="<c:out value="${g.idgrupo}" />"><c:out value="${g.nome}" /></option>
    	</c:if>
    	</c:forEach>
    </select>

Mandei ele comparar o if pela variável do result…

Abração

Rafael_Guerreiro

Ai sim hein!

Bom, agora edita o primeiro post e coloca [Resolvido] para ajudar outras pessoas!

Criado 11 de janeiro de 2012
Ultima resposta 13 de jan. de 2012
Respostas 16
Participantes 2