GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Dúvida no formulario Crud com Struts 2 annotation e Hibernate


#1

Olá,

estou iniciando meus estudos com struts 2 annotation e surgiu uma dúvida:
Cenário:
classes: contato , contatoscont (agenda de um contato)
fkidcontato (contatoscont) referencia id de contato segue abaixo as classes com os mapeamentos:

ContatocontAction

package br.com.paulo.actions;
import java.util.List;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.hibernate.Session;
import org.hibernate.Transaction;
import br.com.paulo.classes.Contatoscont;
import com.googlecode.s2hibernate.struts2.plugin.annotations.SessionTarget;
import com.googlecode.s2hibernate.struts2.plugin.annotations.TransactionTarget;
@ParentPackage("hibernate-default")
@InterceptorRef("basicStackHibernate")
public class ContatoscontAction {
Contatoscont contatoscont;
List<Contatoscont> contatosconts;
	@SessionTarget
	Session hSession;
	@TransactionTarget
	Transaction hTransaction;
		@Action(value="novocontatocont", 
		results={@Result (name="sucesso", location="/paginas/cadcontatoscont.jsp")})
	public String novo(){
			try{
			return "sucesso";	
			}catch(Exception e){
				e.printStackTrace();
			return "erro";	
			}
		}
		@Action(value="salvarcontatocont",
		results={@Result (name="sucesso", location="/paginas/listarcontatoscont.jsp")})
	public String salvar(){
			try{
				hSession.saveOrUpdate(contatoscont);
				return "sucesso";
			}catch (Exception e) {
				e.printStackTrace();
				return "erro";
			}
		}
	@SuppressWarnings("unchecked")
	public List<Contatoscont> getContatoscont(){
		try {
		contatosconts = hSession.createCriteria(Contatoscont.class).list();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return contatosconts;
	}
	@Action(value="listarcontatocont",
			results={@Result(name="sucesso", location="/paginas/listarcontatoscont.jsp")})
	public String listar(){
		try {
			getContatoscont();
			return "successo";
		} catch (Exception e) {
			e.printStackTrace();
			return "erro";
		}
	}
}

Contatocont (classe mapeada)

package br.com.paulo.classes;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="contatoscont")
public class Contatoscont implements Serializable{
	private static final long serialVersionUID = 1L;
	private int id;
	private String nome;
	private String telefone;
	private Contato contato;
	@Id
	@GeneratedValue
	@Column(name="id")
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@Column(name="nome")
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	@Column(name="telefone")
	public String getTelefone() {
		return telefone;
	}
	public void setTelefone(String telefone) {
		this.telefone = telefone;
	}
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "fkidContato")
	public void setContato(Contato contato) {
		this.contato = contato;
	}
	public Contato getContato() {
		return contato;
	}
}

formulario

<%@ taglib uri="/struts-tags" prefix="s" %>
<%@ taglib uri="/struts-dojo-tags" prefix="sx" %>
<%@ page language="java" pageEncoding="ISO-8859-1"%>
<s:head/>
<sx:head/>
<s:form action="salvarcontatocont">
	<s:hidden name="contato.id" ></s:hidden>
	<s:textfield label="Nome" name="contatoscont.nome" ></s:textfield>
	<s:textfield label="Telefone" name="contatocontatocont.telefone" ></s:textfield>
	<s:if test="contato==null">
		<s:set name="btnMessage" value="%{'Incluir Contato'}"></s:set>
	</s:if>
	<s:else>
		<s:set name="btnMessage" value="%{'Salvar Contato'}"></s:set>
	</s:else>
	<s:submit value="%{#btnMessage}"></s:submit>
</s:form>

Como setar o id do contato no formulario?


#2

Amigo,

Esse sei "id" deve preferenciamente gerado pelo banco (via autoincremento ou sequences). Existe ainda a opção de "autoincremento" pelo Hibernate, mas acho que isso só pode ser feito com XMLs.
Você pode, na Action, fazer um "select max" para setar manualmente o "id", mas isso seria, na minha opinião, uma POG.

Agora, quanto ao seu código, algumas considerações pessoais:

Evite resultados "sucesso", "erro"... Assim você tme mais chances de erro. Preira as constanstes SUCCESS, ERROR, INPUT e LOGIN que vêem da ActionSupport. Sei que não é preciso você estender essa classe para criar uma Action mas é sempre bom fazê-lo porque ela traz métodos preciosos, como input(), validate(), getText(), addActionErros(), addActionMessages(), dentre outros.

Outra: não precisa ficar indicando todos os detalhes de resultados. Use o poder do "Convention over configuration" do Struts2.
Exemplo: O método

@Action(value="salvarcontatocont",     
results={@Result (name="sucesso", location="/paginas/listarcontatoscont.jsp")}) 
public String salvar(){  
  try{  
    hSession.saveOrUpdate(contatoscont); 
    return "sucesso";     
  }catch(Exception e){  
    e.printStackTrace();  
    return "erro";    
  }  
}

poderia ficar apenas

@Action("salvarcontatocont")  
public String salvar(){  
  try{  
    hSession.saveOrUpdate(contatoscont); 
    return SUCCESS;     
  }catch(Exception e){  
    e.printStackTrace();  
    return ERROR;    
  }  
}

Assim, os mapeamentos para esse método ficariam, automaticamente:
SUCCESS ("success") - WEB-INF/content/salvarcontatocont.jsp
ERROR ("error") - WEB-INF/content/salvarcontatocont.jsp
INPUT ("input") - WEB-INF/content/salvarcontatocont.jsp

Esses 3 mapeamentos automáticos só não ocorrerão caso você tenha configurado mapeamentos globais no struts.xml.

Mas, pelo visto você não quer que tal mapeamento sempre caia na mesma JSP, correto? Então batsa você criar esses arquivos (isso mesmo, só criar esses):
WEB-INF/content/salvarcontatocont-success.jsp
WEB-INF/content/salvarcontatocont-error.jsp
WEB-INF/content/salvarcontatocont-input.jsp

A simples existência dos arquivos com esse nome faz o Struts2 gerar os mapeamentos pra você. Veja que passa a não existir a necessidade do método "novo()" na sua Action.

Assim, para chamar o JSP de formulário bastaria http://seuhost:suaporta/seucontexto/[color=darkblue]salvarcontatocont[/color][color=blue]!input[/color].

Agora, um detalhe que me chamou atenção é que após salvar você chamara uma JSP de "listagem", mas onde você carregou a lista do banco? Nesse caso, ou você já tem o método "listar()", use um result "redirectAction".


#3

Obrigado pelas dicas. vou segui-las.
Mas a minha duvida inicial persiste:
o id da tabela pessoa e pessoacont é gerada pelo banco mesmo. A minha duvida está no jsp exemplo:

na classe pessoacont eu tenho um objeto da classe pessoa com o mapeamento manytoone. no banco a coluna é a fkidpessoa

a minha dúvida é como eu vou setar o id da classe pessoa no objeto pessoa da classe pessoacont, olha só:

 <s:textfield label="Nome"  name="contatoscont.nome" ></s:textfield>
??? aqui é minha duvida ?? preencher um combo com os contatos da classe pessoa, pegar o selecionado e passar o id para contatoscont.pessoa.id ??

#4

Amigo, ainda não entendi bem sua dúvida. Que classe Pessoa é essa?
Faz o seguinte... monta ai um fake da tela que vc quer q apareca e manda o screenshot.


#5

Veja:
Estou fazendo um CRUD onde tenho a seguinte estrutura:

pessoa (id, nome)

contatocont(id, nomecontato, telefone, pessoa(esse é um objeto da classe acima manytoone ou seja aqui eu preciso do id da classe pessoa como chave estrangeira))

eu queria saber como listar os nomes da classe pessoa em um combo no formulario e quando eu postar o formulario que chamara a action que salva um contatocont o atributo contatocont.pessoa.id ser id selecionado na combo.

me fiz entender?


#6