Erro ao efetuar validation() em um form
22/08/2012 18:04
0
Boa tarde pessoal,

Estou com um problema curioso ao tentar validar um bean que tem relação de um para um e de um para varios... bom, deixe eu explicar.

Eu tenho uma classe Usuario, a mesma guarda atributos comuns a todos os usuários e tem como objetivo exclusivo a validação do mesmo, segue código:

class Usuario {

transient springSecurityService
transient senha2

Date dataCriacao = new Date()
StatusType status
UsuarioType tipoUsuario
Instituicao instituicao
Profissional profissional
Cliente cliente
String nome
String sobrenome
boolean termos
String email
String senha
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
}


Como vocês podem perceber, existem 3 tipos distintos de usuário:
[list]
Instituicao instituicao
Profissional profissional
Cliente cliente
[/list]

Vou pegar a classe cliente como exemplo:

class Cliente {

String avatar
GeneroType genero
Date dataDeNascimento
List enderecos = new ArrayList()
String planosDeSaude

static belongsTo = Usuario

static hasMany = [enderecos: Endereco]

static constraints = {
avatar(blank: true, nullable: true, maxsize: 50)
genero(blank: false, nullable: false, inList:GeneroType.list(), minSize:1, maxSize:1)
dataDeNascimento(blank: false, nullable: false, maxsize: 8)
planosDeSaude(blank:false, nullable: true, maxsize: 500)
}
static mapping = {
table 'cliente'
dataDeNascimento column: 'Data_Nascimento'
genero column: 'Genero'
avatar column: 'Avatar_Arq'
planosDeSaude column: 'Planos_De_Saude'
enderecos cascade:"all-delete-orphan"
}

def getEnderecosList() {
return LazyList.decorate(
enderecos,
FactoryUtils.instantiateFactory(Endereco.class))
}

}


Como vocês podem ver, todo cliente é um usuário (belongsTo) e tem vários endereços (hasMany), sendo que o endereço esta sendo tratado como uma list.

Finalmente o codígo da classe Endereco:

class Endereco implements Serializable {

int index
boolean status
String cep
String logradouro
String complemento
String bairro
String cidade
String estado
String tipoLocal
String descricaoLocal
Double latitude
Double longitude

static belongsTo = [profissional: Profissional,instituicao: Instituicao,cliente: Cliente]
}


Dai vem o problema, quando eu tento avalidar um Cliente no meu controller, ele não avalia.

		
def sessionUsuario = springSecurityService.principal
Usuario usuario = Usuario.get(sessionUsuario.id)

usuario.properties = params

Cliente cliente
if (usuario.cliente == null){
cliente = new Cliente(params)
}else{
cliente = Cliente.get(usuario.cliente.id)
cliente.properties = params
}

if(cliente.enderecos != []){
cliente.enderecos[0].status = true
List localizacao = cliente.enderecos[0].cidade.split("\;")
if(localizacao[0] != null) { cliente.enderecos[0].cidade = localizacao[0] } if(localizacao[1] != null) { cliente.enderecos[0].estado = localizacao[1] }
}

if(params.dataDeNascimento != ""){
cliente.dataDeNascimento = new Date().parse("dd/MM/yyyy", params.dataDeNascimento)
}

if (usuario.validate() & cliente.validate()){
if(usuario.save(flush: true) & cliente.save(flush: true)){
usuario.setCliente(cliente)


O usuario e cliente são validados corretamente, mas somente a class usuario retorna erro ao utilizar a tag <g:hasErrors>, e o cliente mesmo recebendo campos inválidos tais como dataDeNascimento = null não retorna nenhum error.

<g:renderErrors bean="${usuario}" />
<g:renderErrors bean="${cliente}" />

Ai vem a parte curiosa, se eu dou um usuario.setCliente(cliente) antes da validação e valido a class usuario, ele valida corretamente e me retorna os errors do usuario, cliente (incluindo os errors dos enderecos cadastrados).

Mas ele duplica o texto e apresenta a seguinte mensagem de erro

O campo [dataDeNascimento] da classe [] não pode ser vazia
O campo [bairro] da classe [] não pode ficar em branco
O campo [cep] da classe [] não pode ficar em branco
O campo [cidade] da classe [] não pode ficar em branco
O campo [complemento] da classe [] não pode ficar em branco
O campo [estado] da classe [] não pode ser vazia
O campo [logradouro] da classe [] não pode ficar em branco
O campo [bairro] da classe [] não pode ficar em branco
O campo [cep] da classe [] não pode ficar em branco
O campo [cidade] da classe [] não pode ficar em branco
O campo [complemento] da classe [] não pode ficar em branco
O campo [estado] da classe [] não pode ser vazia
O campo [logradouro] da classe [] não pode ficar em branco
O campo [genero] da classe [] não pode ser vazia




| Error 2012-08-22 14:54:51,082 [http-bio-6060-exec-7] ERROR errors.GrailsExceptionResolver - PSQLException occurred when processing request: [POST] /udoctor/cadastro/updateProfileCliente - parameters:
dataDeNascimento:
genero:
enderecos[0].complemento:
sobrenome: Marchena Parreira
enderecos[0].cidade:
email: danielp@r7.com
enderecos[0].cep:
nome: Daniel
enderecos[0].bairro:
enderecos[0].logradouro:
ERRO: inserção ou atualização em tabela "usuario" viola restrição de chave estrangeira "fkf814f32e30381fcb"
Detalhe: Chave (id_cliente)=(11) não está presente na tabela "cliente".. Stacktrace follows:
Message: could not update: [br.com.udoctor.seguranca.Usuario#4]; SQL [update usuario set version=?, account_expired=?, account_locked=?, Id_Cliente=?, Data_Criacao=?, Email=?, enabled=?, Id_Instituicao=?, Nome=?, password_expired=?, Id_Profissional=?, Senha=?, Sobrenome=?, Status=?, Termos=?, Tipo_Usuario=? where id=? and version=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not update: [br.com.udoctor.seguranca.Usuario#4]
Line | Method
->> 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
Caused by ConstraintViolationException: could not update: [br.com.udoctor.seguranca.Usuario#4]
->> 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
Caused by PSQLException: ERRO: inserção ou atualização em tabela "usuario" viola restrição de chave estrangeira "fkf814f32e30381fcb"
Detalhe: Chave (id_cliente)=(11) não está presente na tabela "cliente".
->> 2101 | receiveErrorResponse in org.postgresql.core.v3.QueryExecutorImpl
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1834 | processResults in ''
| 255 | execute . in ''
| 510 | execute in org.postgresql.jdbc2.AbstractJdbc2Statement
| 386 | executeWithFlags in ''
| 332 | executeUpdate in ''
| 105 | executeUpdate in org.apache.commons.dbcp.DelegatingPreparedStatement
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run in java.lang.Thread


Alguem pode me dar uma dica do que fazer?
Tags: Erro, duplicado, one to many, one to one, Endereço


Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto