Pessoal, antes de começar gostaria de dizer que tenho gostado muito do Grails.
Estamos conseguindo criar com muita facilidade uma aplicação que se feita em Java exigiria muito mais trabalho.
Pois é, facilidades a parte, vamos ao problema:
É o seguinte:
em uma herança, não consigo reaproveitar em uma subclasse o registro da SUPER CLASSE salvo por outra subclasse.
Possuo uma classe Pessoa da qual herdam várias outras, tais como Analista e Diretor.
Acontece que a mesma Pessoa é Analista e Diretor.
Quando salvo um Analista não consigo usar os mesmos dados dele para salvar um Diretor de forma que fique claro que são a mesma Pessoa.
Caso não queiram ler todo o post, penso que podem ir direto ao tópico "Simulando o problema:"
Explicando o problema:Na aplicação que estamos desenvolvendo um existem alguns conceitos que não possuem um CPF. É o caso do Projetista, que no nosso caso não possui CPF. Além do Projetista existem outros casos de pessoas sem CPF ou qualquer código único.
Um Analista é uma Pessoa e um Diretor também.
Estou usando a estratégia uma tabela para cada classe de domínio, para separar melhor os conceitos (tablePerHierarchy false).
Quando uma Pessoa possui um código identificador (no caso do CPF para o Diretor) este código é usado para ser o seu id.
Quando a Pessoa não possui um código identificador eu uso uma classe geradora de código e gero um id com 15 dígitos, que não pode ser confundido com o CPF ou com o CNPJ (existe também o conceito de Empresa, que possui CNPJ, mas que é irrelevante para o problema que preciso resolver).
Vejam a seguir o código a CLASSE Pessoa:
import utils.GeradorDeCodigo;
class Pessoa {
public final static String TIPO_PESSOA_FISICA = "PF";
public final static String TIPO_PESSOA_JURIDICA = "PJ";
BigInteger codigoIdentificador;
String nome;
String nacionalidade="Brasileira";
String telefone;
String email;
String tipo = TIPO_PESSOA_FISICA;
static transients=['codigoIdentificador'];
static mapping = {
tablePerHierarchy false
table 'pf_pessoa'
sort 'nome'
version true
id generator:'assigned', column:'pes_id'
nome column:'pes_nome'
nacionalidade column:'pes_nacionalidade'
telefone column:'pes_telefone'
email column:'pes_email'
tipo column:'pes_tipo'
}
/* EVENTOS */
transient beforeInsert = {
if ((this.codigoIdentificador) && (this.codigoIdentificador > 0)) {
this.id = this.codigoIdentificador;
} else {
this.id = GeradorDeCodigo.gerarProximo(Pessoa.class.getName());
}
}
}
Agora, vejam o código da CLASSE Analista:
class Analista extends Pessoa {
String situacao;
String cpf;
void setCpf(String value) {
// seta o Código Identificador do conceito de Pessoa
this.codigoIdentificador = new BigInteger(value);
}
static mapping = {
table 'pf_analista'
version true
id column: 'ana_id'
situacao column:'ana_situacao'
cpf column:'ana_cpf'
}
static constraints = {
situacao(maxSize: 1, inList:["A", "I"])
cpf(size: 0..11, blank:true, nullable:true)
}
}
Por fim, vejam o código da CLASSE Diretor:
class Diretor extends Pessoa {
String cpf;
void setCpf(String value) {
// seta o Código Identificador do conceito de Pessoa
this.codigoIdentificador = new BigInteger(value);
}
static mapping = {
tablePerHierarchy false
table 'pf_diretor'
sort 'nome'
version true
id column: 'dr_id'
cpf column:'dr_cpf'
}
static constraints = {
cpf(size: 0..11, blank:true, nullable:true)
}
}
Com as classes acima, possuo no banco de dados as seguintes tabelas:
pf_pessoa,
pf_analista e
pf_diretor;
Simulando o problema:Acontece que a mesma Pessoa é Analista e Diretor.
Quando salvo um Analista não consigo usar os mesmos dados dele para salvar um Diretor de forma que fique claro que são a mesma Pessoa.
Para simular o problema criei um código que faz o seguinte:
1 - Cria e salva um Analista. Indiquei de propósito um CPF para ele.
2 - Cria um Diretor e tenta salvar com o mesmo CPF do Analista. Estou querendo indicar que esta Pessoa é aquela mesma Pessoa que é Analista.
Vejam o código:
class testeHerancaController {
def testar = {
Acionista oAcionista = new Acionista();
oAcionista.nome = "weber3";
oAcionista.email = "webermiranda3@sic.goias.gov.br";
oAcionista.telefone = "6232015536";
oAcionista.cpf = "12345678901";
oAcionista.save(flush:true);
Diretor oDiretor = new Diretor();
oDiretor.nome = "weber3";
oDiretor.email = "webermiranda3@sic.goias.gov.br";
oDiretor.telefone = "6232015536";
oDiretor.cpf = "12345678901";
oDiretor.save(flush:true); // ERRO AQUI
}
}
Quando eu mando salvar o Diretor (oDiretor.save) recebo um erro de chave duplicada no bacno de dados.
Neste exemplo eu simplifiquei a situação para facilitar o entendimento, mas os conceitos que herdam de Pessoa possuem vários atributos que diferenciam de um conceito para outro.
A pergunta é:Como vou fazer para conseguir dizer que um Diretor é uma Pessoa que já existe em minha base de dados?
Valeu pela atenção e espero que possam me ajudar.