Hibernate + JSF ajuda

12 respostas
J

OLa pessoal sou iniciante em java e seguindo o tutorial JSF aki do site
e a apostila 28 da caelum, tentei juntar os 2.
Na pagina de insercao ele seta os campos da classe agenda e chama o metodo:
<h:commandButton value=“Inserir” action="#{agenda.inserir}"/>

Mas com o hibernate as coisas mudaram, n tenho mais o inserir dentro da classe agenda
e sim dentro de um Dao generico…porem nao posso apenas chamar o Dao e dar
adiciona() pois ele pede um objeto agenda…como faco pra finalizar essa insercao?

Se n der pra entender eu posto os arquivos
Obrigado pessoal.

12 Respostas

jimjr_ivan

Lá vai:

Lembre-se, você está trabalhando com mvc. Portanto, vc terá que criar uma classe Control, no caso, ActAgenda, vc terá que mapear essa classe no facesConfig.xml criando o bean, com isso, através do bean vc consegue chamar a classe.

<h:commandButton value="Inserir" action="{actAgenda.inserir}"/>

Bom, no método inserir da classe actAgenta, você terá que fazer a validação dos dados, e chamar o objeto Dao que fará a persistência no banco, de uma olhada no código abaixo:

public void Inserir() {   
   if (valid()) {
       AgendaDao agendaDao = new AgendaDao();
       try {
          agendaDao.save(agenda);
       catch (Exception e) {
          e.printStackTrace();
       }
   }
}

belê?
espero que tenha entendido.

J
Opa ajudou sim, era o que eu tinha em mente, seria assim:
package controle;

import classes.Pessoa;
import dao.DaoFactory;

public class contPessoa {
	
	public Pessoa pessoa;
	private final DaoFactory daoFactory;
	
	public contPessoa(DaoFactory daoFactory) {	
		this.daoFactory = daoFactory;
	}
	
	public void adiciona () {
		this.daoFactory.beginTransaction();
		this.daoFactory.getPessoaDao().adiciona(pessoa);
		this.daoFactory.commit();
	}
}
package dao;

import org.hibernate.Session;
import org.hibernate.Transaction;

import util.HibernateUtil;
import classes.Pessoa;

public class DaoFactory {

	private final Session session;
	private Transaction transaction;

	private DaoFactory() {
		session = HibernateUtil.getSession();
	}

	public void beginTransaction() {
		this.transaction = this.session.beginTransaction();
	}

	public void commit() {
		this.transaction.commit();
		this.transaction = null;
	}

	public boolean hasTransaction() {
		return this.transaction != null;
	}

	public void rollback() {
		this.transaction.rollback();
		this.transaction = null;
	}

	public void close() {
		this.session.close();
	}

	public Dao<Pessoa> getPessoaDao() {
		return new Dao<Pessoa>(this.session, Pessoa.class);
	}
}
package dao;

import java.util.List;

import org.hibernate.Session;

public class Dao<T> {

	private Session session;
	private final Class classe;

	Dao(Session session, Class classe) {
		this.session = session;
		this.classe = classe;
	}

	public void adiciona(T u) {
		this.session.save(u);
	}

	public void atualiza(T u) {
		this.session.merge(u);
	}

	public void remove(T u) {
		this.session.delete(u);
	}

	public List<T> listaTudo() {
		return this.session.createCriteria(this.classe).list();
	}
	
	public T procura(Long id){
		return (T) session.load(this.classe ,id);
	}
}
Mas estou com um duvida, se ja tive que criar um Dao com um metodo adicionar para fazer o save, porque fazer ma outra chamada inserir q chame a adicionar. Nao poderia ser feito tudo no Dao? orbigado!
J

up

felipeguerra

Vc tem que evitar o acoplamento entre as camadas…

J
package controle;

import classes.Pessoa;
import dao.DaoFactory;

public class contPessoa extends Pessoa{
	
	private final DaoFactory daoFactory;
	
	public contPessoa(DaoFactory daoFactory) {	
		this.daoFactory = daoFactory;
	}

	public void adiciona () {
		this.daoFactory.beginTransaction();
		this.daoFactory.getPessoaDao().adiciona(AQUI);
		this.daoFactory.commit();
	}
}
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@page contentType="text/html;charset=UTF-8"%>
<html>
<body>
<f:view>
<h:form>
<center><h2> Inserção </h2></center>
<br>
<h3>Entre com os dados abaixo</h3>
<table>
<tr>
<td>Nome:</td>
<td>
<h:inputText value="#{controle.nome}"/>
</td>
</tr>
<tr>
<td>Endereço:</td>
<td>
<h:inputText value="#{controle.endereco}"/>
</td>
</tr>
<tr>
<td>Cidade:</td>
<td>
<h:inputText value="#{controle.cidade}"/>
</td>
</tr>
<tr>
<td>Telefone:</td>
<td>
<h:inputText value="#{controle.telefone}"/>
</td>
</tr>
</table>
<p>
<h:commandButton value="Inserir" action="#{controle.adicionar}"/>
</p>
</h:form>
<br>
<h:outputLink value="index.jsf">
<f:verbatim>voltar</f:verbatim>
</h:outputLink>
</f:view>
</body>
</html>
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
                              "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
 <managed-bean>
  <managed-bean-name>agenda</managed-bean-name>
  <managed-bean-class>classes.Pessoa</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
 </managed-bean>
  <managed-bean>
  <managed-bean-name>controle</managed-bean-name>
  <managed-bean-class>controle.contPessoa</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
 </managed-bean>
 <navigation-rule>
  <from-view-id>/buscar.jsp</from-view-id>
  <navigation-case>
   <from-outcome>success</from-outcome>
   <to-view-id>/sucesso_busca.jsp</to-view-id>
  </navigation-case>
  <navigation-case>
   <from-outcome>failure</from-outcome>
   <to-view-id>/falha_busca.jsp</to-view-id>
  </navigation-case>
 </navigation-rule>
 <navigation-rule>
  <from-view-id>/inserir.jsp</from-view-id>
  <navigation-case>
   <from-outcome>success</from-outcome>
   <to-view-id>/sucesso_insercao.jsp</to-view-id>
  </navigation-case>
  <navigation-case>
   <from-outcome>failure</from-outcome>
   <to-view-id>/falha_insercao.jsp</to-view-id>
  </navigation-case>
 </navigation-rule>
</faces-config>
Nao estou conseguindo passar o objeto Pessoa como parametro ali no AQUI. Como faco para instanciar o pessoa que esta recebendo os valores pelo pessoa.nome dos inputs

Obrigado

Marky.Vasconcelos

Crie um handler

public class PessoaHandler(){
  private final DaoFactory daoFactory;  
 private final Pessoa pessoa;

     public Pessoa getPessoa(){
         return pessoa;
      }  
     public PessoaHandler() {//Construtor vazio, o JSF não passa nenhum argumento ao instanciar ManagedBeans (Ou faz e eu não sei :p)    
         this.daoFactory = new DaoFactory();//Ou o modo que você instancia essa classe  
     }  
   
     public void adiciona () {  
         this.daoFactory.beginTransaction();  
         this.daoFactory.getPessoaDao().adiciona(pessoa);  
         this.daoFactory.commit();  
     }  
 }

Para acessar os atributos da classe Pessoa é só colocar na expressão o caminho

Ao invés:

#{controle.nome}

use:

#{controle.pessoa.nome}

Herança não é uma boa ideia para um controlador.

felipeguerra

Você tem um atributo na classe Pessoa que possa ser herdado e passado como parâmeto?

J
Mark, me retorna o seguinte erro antes mesmo de acessar o arquivo de insercao.
org.apache.jasper.JasperException: javax.servlet.jsp.JspException: javax.faces.FacesException: javax.faces.FacesException: Can't instantiate class: 'controle.contPessoa'.. class controle.contPessoa : java.lang.InstantiationException: controle.contPessoa
	org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:510)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:375)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:322)
	com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:130)
	com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:87)
	com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:200)
	com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:117)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:198)

root cause

javax.servlet.ServletException: javax.servlet.jsp.JspException: javax.faces.FacesException: javax.faces.FacesException: Can't instantiate class: 'controle.contPessoa'.. class controle.contPessoa : java.lang.InstantiationException: controle.contPessoa
	org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:854)
	org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:791)
	org.apache.jsp.inserir_jsp._jspService(inserir_jsp.java:82)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:322)
	com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:130)
	com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:87)
	com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:200)
	com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:117)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:198)
felipe:
package classes;
import javax.persistence.*;

@Entity
@Table(name="pessoa",schema="teste")
public class Pessoa {
	@Id
	@GeneratedValue
	@Column(name="pes_codigo")
	private int id;
	private String nome; 
	private String endereco;
	private String cidade;
	private String telefone;

	public Pessoa() {
	}
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	public String getNome() {
		return nome;
	}

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

	public String getCidade() {
		return cidade;
	}

	public void setCidade(String cidade) {
		this.cidade = cidade;
	}

	public String getEndereco() {
		return endereco;
	}

	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}

	public String getTelefone() {
		return telefone;
	}

	public void setTelefone(String telefone) {
		this.telefone = telefone;
	}
}
Marky.Vasconcelos

É que ele não encontra a classe controle.contPessoa para instanciar.
Você tem que ter ela no faces-config
Na classe PessoaHandler declare o package que eu acho que é controle;

package controle;

public class PessoaHandler{ //...

No Faces-config configure o ManagedBean

<managed-bean>  
   <managed-bean-name>pessoaHandler</managed-bean-name>  
   <managed-bean-class>controle.PessoaHandler</managed-bean-class>  
   <managed-bean-scope>session</managed-bean-scope>  
 </managed-bean>

Na páginas JSF: (Arrumei uma parte depois você altera o resto)

//...
 <h:inputText value="#{pessoaHandler.pessoa.cidade}"/>  
 </td>  
 </tr>  
 <tr>  
 <td>Telefone:</td>  
 <td>  
 <h:inputText value="#{pessoaHandler.pessoa.telefone}"/>  
 </td>  
 </tr>  
 </table>  
 <p>  
 <h:commandButton value="Inserir" action="#{pessoaHandler.adicionar}"/>
<!-- note que o método adicionar é do Handler e não do Objeto pessoa -->
 </p>  
 </h:form>  
//...
J
mesmo assim ele diz nao encontrar o xxx.pessoa.nome, veja:: faces
<managed-bean>
  <managed-bean-name>contPessoa</managed-bean-name>
  <managed-bean-class>controle.contPessoa</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
 </managed-bean>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@page contentType="text/html;charset=UTF-8"%>
<html>
<body>
<f:view>
<h:form>
<center><h2> Inserção </h2></center>
<br>
<h3>Entre com os dados abaixo</h3>
<table>
<tr>
<td>Nome:</td>
<td>
<h:inputText value="#{contPessoa.pessoa.nome}"/>
</td>
</tr>
<tr>
<td>Endereço:</td>
<td>
<h:inputText value="#{contPessoa.pessoa.endereco}"/>
</td>
</tr>
<tr>
<td>Cidade:</td>
<td>
<h:inputText value="#{contPessoa.pessoa.cidade}"/>
</td>
</tr>
<tr>
<td>Telefone:</td>
<td>
<h:inputText value="#{contPessoa.pessoa.telefone}"/>
</td>
</tr>
</table>
<p>
<h:commandButton value="Inserir" action="#{contPessoa.adicionar}"/>
</p>
</h:form>
<br>
<h:outputLink value="index.jsf">
<f:verbatim>voltar</f:verbatim>
</h:outputLink>
</f:view>
</body>
</html>
package controle;

import classes.Pessoa;
import dao.DaoFactory;

public class contPessoa {
	
	private final DaoFactory daoFactory;

	private Pessoa pessoa;

	public Pessoa getPessoa() {
		return pessoa;
	}

	public contPessoa(DaoFactory daoFactory) {
		this.daoFactory = daoFactory;

	}

	public void adiciona() {
		this.daoFactory.beginTransaction();
		this.daoFactory.getPessoaDao().adiciona(pessoa);
		this.daoFactory.commit();
	}
}
o public contPessoa nao pode ser sem parametro pois sua o metodo q inicia sua classe esta como private, mesmo mudando pra public gera um outro problema. Creio q ele n esteja reconhecendo esse pessoa... Obrigado hein
J

up

Marky.Vasconcelos

O JSF não aceita parametros para a inicialização

Você tem que ter um construtor publico e vazio.

Procure outro modo de instanciar a DaoFactory, Singleton por exemplo funcionaria, não é o mais indicado, mas você tem que deixar um construtor em branco.

E outra coisa

Em nome de classes sempre começe com letra maiuscula
para métodos e atributos começe com letra minuscula.
Isso não é uma regra mas é uma convenção que facilita a leitura do código por outros programadores.

Criado 18 de janeiro de 2008
Ultima resposta 23 de jan. de 2008
Respostas 12
Participantes 4