Grails 1.0.1 e many-to-many com GORM DSL

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:
class Usuario {
static mapping = {
privilegios column:'privilegio_id', joinTable:'usuario_priv'
}
}
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.

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