Magno, chegou a olhar essa documentação?
http://gorm.grails.org/6.0.x/hibernate/manual/#multiTenancy
Sim, mas não fala tudo que voce precisa saber.
Por exemplo, vc nunca deve realizar operações multi tenant no contexto de uma transação controlada por anotações (@Transaction).
Sempre utilize Domain.withTransaction {}
Outra coisa que tive que descobrir na cabeçada é que o framework não preenche automaticamente o tenantid dos domains, vc precisa fazer isso na mão e a documentação nao menciona esse fato rs.
Outra coisa, se você quiser utilizar o método Domain.withSession em um projeto que utilize multi tenant, precisa garantir que o seu haja um tenant setado(seu tenantresolver precisa retornar algo não nulo). Acontece que para mim esse comportamento não faz sentido, o meu projeto pode ser multi tenant porém antes de realizar o login eu posso simplesmente nao definido qual o tenant daquela sessão, e isso também não é documentado.
Enfim, acho que foi lançado de forma imatura. Estou tentando utilizar isso para implementar um modo "multi empresa" no projeto
Sempre tentei usar o Multi Tenancy, mas nunca consegui um protótipo funcional. alguém conhece algum tutorial de como implementar passo a passo o multi tenancy?
Ainda não tinha testado Multi Tenancy mas pelo que tinha lido, realmente não expões esses pontos que você levantou. Acabou dando várias dicas que deveriam ter ao menos notas na documentação alertando.
Rodrigo,
O grosso é o que está explicado na documentação do gorm 6. Você precisa ir nas configurações do projeto (application.yml) grails.gorm.multiTenancy.mode para DISCRIMINATOR/DATABASE/SCHEMA.
Isso diz respeito a como os dados de cada tenant serão separados:
* discriminator: Os domains que são multi tenant tem um atributo (por padrão chamado tenantId) para diferenciar
* database: Um banco de dados separado para cada tenant
* schema: Um unico banco de dados mas com schemas para cada tenant
grails.gorm.multiTenancy.tenantResolverClass deve apontar para o nome de uma classe que implementa TenantResolver, essa classe vai ser consultada pelo Grails sempre que precisar saber o id do tenant ativo naquele request, existem implementações prontas para obter esse dado de um atributo da sessão, de um cookie, do subdomain da aplicação, etc.
Os domais que são multi tenant devem implementar o trait MultiTenant<T> onde T é o proprio domain, ex:
class ContaPagar implements MultiTenant<ContaPagar> {
}
Algo que ficou nebuloso para mim lendo a documentação e confesso que nao fiz testes para verificar é se você pode simplemente utilizar os métodos de consulta do gorm e ele automaticamente vai filtrar pelo tenant, ou se tem que utilizar Tenants.withCurrent. Em todo caso, segue explicação:
Chame Tenants.withCurrent {} passando uma closure, essa closure será invocada no contexto do tenant atual, então todas as operações de consulta levarão o tenant atual em consideração.
A documentação vai +- até aí, como eu disse em outra mensagem ainda tem alguns detalhes que vc tem que ficar ligado, exemplo, jamais utilize @Transactional com tenant, ao invés utilize domain.withTransaction. Exemplo:
Tenants.withCurrent {
ContaPagar.withTRansaction { transactionStatus ->
}
}
Para salvar domains, o tenantId não é preenchido automaticamente, entao vc tem que preencher antes de salvar:
seuDomain.tenantId = Tenants.currentId
No meu caso eu implementei uma AST onde eu apenas anoto o domain com @Tenant, e ela automaticamente adiciona o trait MultiTenant<T> e adiciona um beforeValidate() que preenche o tenantId antes de salvar