Fórum Como persistir dados de objetos distintos enviados pelo mesmo formulário com JSF? #389575
28/10/2010
0
Marcos Sousa
Curtir tópico
+ 0Posts
28/10/2010
Henrique Weissmann
class ManagedBeanWrapper {
private Hospede hospede;
private Carro carro;
// Crie getters e setters que referenciem atributos dos atributos internos, tal como no exeplo abaixo:
public String getNomeHospede() {return getHospede().getNome();}
public void setNomeHospede(String valor) {getHospede().setNome(valor;)}
}
Quanto ao salvamento, na action que for persistir os dados, basta tratá-los individualmente.
Gostei + 0
30/10/2010
Marcos Sousa
Mais na hora de persistir os dados estou com problemas, ele me retorna um sucesso na operação mais ao consultar minha base de dados os unicos dados que são gravados na base são de hospede os dados referentes ao Carro não são persitidos. Veja como criei a logica para salvar os dados
public String cadastrar() throws DAOException {
if (hospede.equals(hospede)) {
if (hospede.getId() != null && hospede.getId().intValue() > 0) {
hospedeDAOImpl.alterarEntidade(hospede);
return "sucessoAlteraHospede";
} else {
hospedeDAOImpl.salvarEntidade(hospede);
return "sucessoCadastraHospede";
}
} else{
if(carro.getId() !=null && carro.getId().intValue() > 0){
carroDAOimpl.alterarEntidade(carro);
return "sucessoAlteraCarro";
} else{
carroDAOimpl.salvarEntidade(carro);
return "sucessoCadastraCarro";
}
}
}
Envio o link para aceso a classe HospedeBean: http://paste-it.net/public/z85f298/
Gostei + 0
30/10/2010
Henrique Weissmann
com base apenas na classe HospedeBean, não há como saber exatamente o porquê dos dados não estarem ainda presentes na sua base de dados, mas com base na minha experiência, posso te apontar duas possibilidades.
* O Hibernate não envia os comandos imediatamente para o servidor de bancos de dados - por padrão, o Hibernate só envia os comandos SQL para a base de dados em lote. Isto é feito ou após algum período de tempo (que pode variar de acordo com a versão do Hibernate) ou quando um número x de comandos está acumulado na sessão.
Solução: execute o método flush da sua session. Isto informa o Hibernate que deve enviar os comandos para a base de dados naquele momento.
* Alguma excessão está ocorrendo durante o processo de persistência e está sendo ignorada. Observe se no código fonte do seu DAO há algum trecho que apresente um padrão similar ao abaixo exposto:
try {
// tudo o que deve ser executado, no caso, a persistência dos dados
} catch (Exception ex) {
// bloco vazio
}
Se o bloco estiver vazio, o código funciona normalmente, sem que a excessão seja detectada. Dica: ao invés de usar Exception, use Throwable. Throwable detecta qualquer problema, inclusive as excessões de execução.
Gostei + 0
30/10/2010
Marcos Sousa
Nos metodos salvarEntidade e alterarEntidade alterei o catch de Exception para Throwable
Fiz um debug na aplicação e percebi que tenho um erro na lógica ao salvar os dados. Olhe o método da classe HospedeBean
public String cadastrar() throws DAOException {
if (hospede.equals(hospede)) {
if (hospede.getId() != null && hospede.getId().intValue() > 0) {
hospedeDAOImpl.alterarEntidade(hospede);
return "sucessoAlteraHospede";
} else {
hospedeDAOImpl.salvarEntidade(hospede);
return "sucessoCadastraHospede";
}
} else{
if(carro.getId() !=null && carro.getId().intValue() > 0){
carroDAOimpl.alterarEntidade(carro);
return "sucessoAlteraCarro";
} else{
carroDAOimpl.salvarEntidade(carro);
return "sucessoCadastraCarro";
}
}
}
Ao executar o método ele pega o objeto hospede e o remete ao else interno que chama o metodo hospedeDAOImpl.salvarEntidade(hospede); Quando ele realiza esta operação ele já faz o returno de sucesso ao cadastrar o hospede e não efetua o cadastro do Carro.
Qual a sugestão para melhorar esta lógica?
Desde já agradeço.
Gostei + 0
30/10/2010
Henrique Weissmann
Nesta mesma classe, também implemento uma função que me retorne true ou false, dizendo se o registro já foi persitido na base de dados ou não. Depende muito do caso, mas normalmente é um teste baseado no atributo que identifica a chave primária, como por exemplo retornar true para campos primários do tipo inteiro ou longo que sejam maiores que zero, indicando se tratar de um registro já presente na base de dados.
Você pode reaproveitar esta característica nos seus managed beans, tal como no seu exemplo. Se você chamasse esta função antes de retornar a string que identifica a navegação, sua vida ficaria mais fácil.
Finalmente, nos DAOs, ao invés de ter um método para salvar e outro para editar, tenho um único chamado persistir. Este verifica o valor da função que me diz se estou lidando com um registro novo ou não e, de acordo com isto, chama o método apropriado do hibernate (save ou update).
Procedendo desta forma, você reduz bastante a complexidade do seu projeto e, consequentemente, a possibilidade de ocorrência de erros.
Gostei + 0
01/11/2010
Marcos Sousa
Desde já agradeço.
Gostei + 0
02/11/2010
Henrique Weissmann
Vamos usar o seu próprio exemplo ok? No caso, as entidades seriam Carro e Hospede. Nesta situação, eu criaria uma classe abstrata chamada Entidade, da qual ambas seriam subclasses cuja implementação seria basicamente a seguinte:
public abstract class Entidade {
// Supondo que o identificador seja do tipo String, e eu use o algoritmo UUID para defini-lo
private String id;
public String getId() {return this.id;}
public void setId(String valor) {this.id = valor;}
/*
Uma vez persistido, o próprio Hibernate irá gerar o valor do atributo ID para mim usando este
algoritmo. Se não tiver ainda sido gerado, é sinal de que ainda não foi inserido na base de dados
*/
public String isPersistido() {
return getId() != null;
}
/*
Estou usando o tipo genérico de excessão apenas para simplificar o exemplo
*/
public void persistir() throws Exception {
if (isPersistido()) {
updateBD();
} else {
incluirBD();
}
}
public void updateBD() throws Exception {
// edição no banco de dados entra aqui
}
public void incluirBD() throws Exception {
// inserção no banco de dados entra aqui
}
}
Gostei + 0
04/11/2010
Marcos Sousa
Criei um pacote chamado exemplo.entity composto pelas classes:
Entidade: http://paste-it.net/public/a02926e/;HospedeTeste: http://paste-it.net/public/e369f9d/;CarroTeste: http://paste-it.net/public/af8725f/Somente em CarroTeste inclui o extends Entidade e ele me apresenta a sugestão de criar o ID para a entidade. Na Entidade tenho os seguintes erros:
public Integer isPersistido(){
return getId() != null; //tipo de retorno incompativel ele requer boolean e recebe Integer.
}
A implementação será desta forma mesmo, o que devo fazer para corrigir estas falhas?
Desde já agradeço.
Gostei + 0
07/11/2010
Henrique Weissmann
no caso, seu erro está no tipo declarado de retorno e o valor que você está retornando.
Repare:
public Integer isPersistido(){
return getId() != null; //tipo de retorno incompativel ele requer boolean e recebe Integer.
}
seu método isPersistido, é do tipo Integer. Mas em seu interior, você está retornando o resultado de uma operação de comparação que, em Java, sempre é um valor booleano.
Reescreva-a da seguinte maneira:
public boolean isPersistido() {
return getId() > 0;
}
Por que isto: supondo que seja um campo autoincremental, o primeiro registro na tabela sempre será 1, e zero quando ainda não foi persistido.
Gostei + 0
16/11/2010
Devmedia
Gostei + 0
17/11/2010
Marcos Sousa
Gostei + 0
06/12/2010
Devmedia
por falta de retorno estamos encerrando o chamado. Caso volte a ter dúvidas sobre o assunto aqui tratado, por favor, volte a postar aqui mesmo e o consultor voltará a lhe atender.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)