Grails (GORM) não suporta multi herança?
23/12/2013 12:18
0
Pessoal, estou fazendo alguns testes com o Graisl para saber se dará certo iniciar um novo projeto (grande projeto) com ele ou não, fazendo alguns testes aqui criei o seguinte cenário nas classes de domínio

class Base {

private static final Date NULL_DATE = new Date(0)
Date createdAt = NULL_DATE;
Date updatedAt = NULL_DATE;

def beforeInsert(){
createdAt = new Date();
updatedAt = new Date();
}

def beforeUpdate(){
updatedAt = new Date();
}

static mapping = {
autoTimestamp true
}
}


abstract class Person extends Base{

String name;
String name2;
String phone1;
String phone2;

static constraints = {
name2 nullable:true
phone1 nullable:true
phone2 nullable:true
}


}


class Customer extends Person {

double credit;

}


Ou seja, tenho uma classe base que é abstrata, depois a classe pessoa que também é abstrata e e herda de Base a classe cliente que herda de pessoa.

Quando eu tento executar lá no boostrap algo como

if (Environment.current== Environment.DEVELOPMENT){
Customer customer = new Customer(name: 'Rodrigo')
customer.save(failOnError: true)

Customer customer1 = new Customer(name: 'Fernanda')
customer1.save(failOnError: true)
}

dá o seguinte errro

Caused by MissingMethodException: No signature of method: agileweb.Customer.save() is applicable for argument types: () values: []
Possible solutions: save(), save(), save(boolean), save(java.util.Map), save(boolean), save(java.util.Map)

Se eu retirar a herança da classe Pessoa para a classe Base, dá certo, inclusive somente uma tabela chamada Pessoa é criada no banco com um campo que discrimina o tipo da classe, porém eu preciso que Pessoa herde de Base, até o momento, com muitas pesquisas eu não achei a solução, estou iniciando no Grails agora, será que o GORM não da suporte a essa estratégia de mapeamento? Como a gente faz no JPA usando o @MapSuperClass ?

Eu quero muito utilizar o Grails, mas estou esbarrando nessas questões
Tags: GORM Herança


0
Cara, eu não entendi o sentido do NULL_DATE, mas para os outros o grails já faz para você.

Basta declarar assim:

Date dateCreated
Date lastUpdated

Pronto, o Grails já sabe o que fazer.
23/12/2013 12:29


0
Olá, veja, a questão não é o private static final Date NULL_DATE = new Date(0), isso é apenas um fragmento de código, já até tirei, o problema é de herança

O problema é que o Gorm não está suportando uma herança com 2 niveis

Pessoa extends Base

Customer extends Pesssoa

assim da erro, que mostrei acima, se eu retirar que "pessoa extends Base", funciona normal, a pergunta é, eu estou fazendo algo errado ai ou realmente o Gorm não dá suporte a esse tipo de mapeamento?
23/12/2013 12:38


0
Fala
Rodrigo Rodrigues
!

É de seu conhecimento que a herança em domains vai criar uma única tabela contendo todos estes parâmetros correto ? Isto é realmente a sua necessidade? Outro ponto, não utilize muito deste artificio, pois para dar prosseguimento você terá que utilizar DSL's para resolver seu pequeno problema. Não faça heranças muito profundas, isso vai lhe custar na performance das suas queries, pois haverá muitos joins a serem realizados.

Outro ponto é que você não pode ter valores nulos neste caso, e pelo código exibido existem valores nulos.

Insira isto na classe base.


static mapping = {
tablePerHierarchy true
}




* O seu problema não é de herança multipla e sim do aprofundamento do nível dela.

* Todas as classes são Domains?


0
Carlos, obrigado pela resposta.

Realmente não é muito legal usar herança com uma profundidade alta, de fato o termo "multi herança" está errado em relação ao que eu queria, depois que eu postei eu percebi mas ai não tinha opção para editar, ou pelo menos eu não vi, também não procurei muito.

Postei isso lá no stackoverflow e me indicaram isso : http://en.wikipedia.org/wiki/Composition_over_inheritance

Composição ao invés de herança quando preciso de algo muito profundo, de fato acho uma abordagem melhor.

Nesse esquema ai, só terá uma tabela, chamada pessoa, que terá Vendedores, Clientes, Funcionários etc.

Mas no caso se eu usar tablePerHierarchy true ele irá criar uma tabela para cada classe, e isso é que gera Joins desnecessários, pelo o que eu vi de fato é mais simples e eficiente usar a Tabela Pessoa.

Do jeito que está ai, funciona legal, cria somente a tabela Pessoa, só da pau mesmo quando eu digo que Pessoa herde de Base que é para aproveitar os campos createdAt, updatedAt e talvez createdby e updateBy, irei ver como obter esse encapsulamento sem um relacionamento profundo, ou seja, usar no máximo nível 1, confesso que ainda não fiz um exemplo para testar a composição por herança.

Uma sugestão para o forum, acho muito importante notificação por email de resposta recebida!
26/12/2013 18:40


0
Base é uma classe de domínio (isto é, reside em grails-app/domain)?



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