Olá,
estou desenvolvendo um pequeno sistema web de gerenciamento financeiro.
O sistema esta funcional. Porém, tem uma falha crítica: Não suporta vários usuários independentes.
Ou seja, eu posso ter diversos usuários cadastrados no sistema, porem todos “enxergam” as mesmas tabelas e os mesmos registros.
Gostaria que cada usuário do sistema tivesse seu próprio banco de dados (não necessáriamente um banco, mas alguma divisão).
Estou utilizando JSF, Hibernate e Spring (apenas autenticação) e apesar de procurar, não encontrei uma solução satisfatória para o problema.
Gostaria de saber se existe alguma solução “padrão” para isso. Sei lah, tipo, criar esquemas diferentes com as mesmas tabelas, ou identificar cada registro no banco com o usuário “dono” do mesmo?
Quais as possíveis soluções?
creio que criar um banco pra cada usuario seria exagero, vc pode identificar o dono do registro adicionando o identificador do usuario ao mesmo.
Ex: o objeto conta ter uma referencia a um Usuario e consequentemente a tabela conta ter um campo (chave estrangeira) idUsuario por exemplo…
creio que para seu caso resolve…
abrassssssss
Será que não existe uma solução transparente?
Tipow, que eu não precisasse ficar inserindo ‘where tabela.id_usuario = X’ em todas as consultas?
como vc mesmo citou, a solucao de um db por usuario, vc cria um db assim que o usuario é criado e sempre que este se logar vc acessa o db dele… nunca fiz isso com hibernate e sinceramente neste caso parece inviavel.
obs: se vc ainda faz queries sql, vc nao esta utilizando corretamente o hibernate.
Mesmo que tenha que adicionar um where a algumas queries nao vejo nenhum overhead nisso. Faz parte da sua logica.
abrassssssss
Utilize Views, passando parâmetro para ela.
Junto com o hibernate?
Como ficaria isso?
Creio que seja dificil que resolva seu caso por vc estar usando hibernate. Mas se ajuda a pensar em alguma coisa veja como seria uma view de dependeria do usuario logado para retornar apenas os registros do usuario
create view v_lancamentos as
select * from lancamentos where dono = CURRENT_USER;
o problema é que a variavel interna CURRENT_USER do postgre faz referencia ao usuario de banco que esta sendo utilizado para acessar os dados.
uma forma de fazer isso seria com uma funcao algo do tipo:
create or replace function f_lancamentos(user text) …
mas sinceramente acho que seria mais conveniente usar clausulas where nas suas consultas 
Vou ver se é possível criar algum filtro nas consultas do hibernate (HQL), que adicione a clausula ‘where’.
Se encontrar alguma solução decente eu posto aqui.
Então, encontrei um solução interessante.
Descobri que existe um tal de Filter no hibernate (Hibernate Filter).
Com esse filter é possível adicionar filtro para todas as consultas que o hibernate fizer. Tanto os HQL qto os Criterion.
Para utilizar esse filtro é relativamente simples.
Nas entidades onde vc deseja que sempre seja adicionado o filtro basta colocar a annotation:
@FilterDef(name="usuarioFiltro", parameters=@ParamDef(type="java.lang.String", name="username") )
@Filter(name="usuarioFiltro", condition=":username = username")
Por exemplo, imagine a entidade Pessoa, que possuí o atributo “username”, que indica qual usuário é o dono do registro. O annotation ficaria +/- assim:
@Entity
@javax.persistence.SequenceGenerator(name = "pessoa_seq", sequenceName = "pessoa_sequence", allocationSize = 1)
@Table(name = "pessoa")
@FilterDef(name="usuarioFiltro", parameters=@ParamDef(type="java.lang.String", name="username") )
@Filter(name="usuarioFiltro", condition=":username = username")
public class Pessoa {
....
String username; //+ getters e setters
}
Um detalhe importante a ser lembrado é que o filtro NÃO é ativado por padrão. Para cada session do hibernate é necessário ativá-lo.
Então, sempre que criar uma session, faça o seguinte:
session.enableFilter("usuarioFiltro").setParameter("username", "usernameUserLogado")
Abraços