Oi pessoal,
primeiro queria divulgar o forum do GrailsBrasil ( www.grailsbrasil.com ). Um ótimo espaço para os brazucas, que cada vez mais descobrem e se encantam com o Grails.
Em seguida, queria falar, com certo atraso, da tão esperada Release 1.0 do Grails, que na verdade já está na 1.0.1. Isso é uma grande notícia.
Por último, a razão deste post....
O Grails 1.0.1 possui o GORM DSL, que oferece grande facilidade para controlar detalhes do mapeamento objeto relacional dos objetos de domínio. Ao migrar uma aplicação do grails 0.6 para o 1.0.1, quis alterar alguns detalhes do mapeamento, já que agoraeu conseguiria isso sem precisar apelar para mapeamento Hibernate com XML.
O problema que eu queria resolver era:
Digamos que eu tenha uma classe Usuario e outra Privilegio, com um relacionamento many-to-many entre elas. Logo teremos:
class Usuario {
String nome
static hasMany = [privilegios:Privilegio]
}
class Privilegio {
String nome
static hasMany = [usuarios:Usuario]
static belongsTo = Usuario
}
Com as classes acima, o grails gera as seguintes tabelas:
usuario
id
nome
privilegio
id
nome
usuario_priv
usuarios_id (que é uma FK para privilegio.id)
privilegios_id (que é uma FK para usuario.id)
É isso mesmo: o campo usuarios_id é uma chave estrangeira para o id da tabela privilegio; e o campo privilegios_id é uma chave estrangeira para o id da tabela usuario. A explicação pra isso está aqui (vejam o comentário do Graeme).Eu não sei quanto a vocês, mas pra mim isso soa muito estranho. Mas é assim mesmo que o grails gera por padrão. A forma que eu gosto de trabalhar é com campos no singular e com o nome do campo da chave estangeira condizente com o nome da tabela de referência:
usuario_priv.usuario_id = usuario.id
usuario_priv.privilegio_id = privilegio.id
Para isso, então, eu antigamente teria que fazer o mapemanto com XML do hibernate (já fiz vários para outras aplicações com grails). Mas agora na versão atual posso fazer o que quero com o GORM DSL. E é isso que quero mostrar, pois há um detalhe que precisei fazer alguns testes até entender o comportamento do Grails com essa DSL. Vamos lá...
class Usuario {
String nome
static hasMany = [privilegios:Privilegio]
static mapping = {
privilegios column:'usuario_id', joinTable:'usuario_priv'
}
}
class Privilegio {
String priv
static hasMany = [usuarios:Usuario]
static belongsTo = Usuario
static mapping = {
usuarios column:'privilegio_id', joinTable:'usuario_priv'
}
}
O que eu acho curioso e anti-intuitivo no código acima, é que numa primeira tentativa eu coloquei:
Mas isso acabou sendo errado. Na verdade temos que colocar como nome da coluna (para ter o resultado que eu esperava), o nome da classe em que me encontro, e não o nome do atributo de relacionamento. Em fim: o correto é o código acima completo das classe Usuario e Privilegio, e não o código acima com fundo avermelhado.class Usuario {
static mapping = {
privilegios column:'privilegio_id', joinTable:'usuario_priv'
}
}
Fiz questão de colocar isso aqui, pois a documentação não me parece muito clara quanto a isso. (talvez eu é que tenha entendido errado a documentação, sei lá....em fim....tá aí pra quem precisar deste detalhe).
Abcs
Felipe