Varias bases de dados em uma aplicação

Olá pessoal,

Estou precisando de uma ajuda… Já procurrei pesquisei muito, mas não encontrei especificamente o que estou precisando. Minha dúvida é:

Estou trabalhando em uma aplicação Web com JPA + Hibernate, e preciso que essa aplicação possa se conectar a bases de dados diferentes, de acordo com o ususário que a acessa.

Ex.:

Usuário Ricardo -> Base Empresa 1
Usuário Jonas -> Base Empresa 2
Usuário José -> Base Empresa 54

Estou usando uma unidade de persistência JTA que usa um pool de conexão do container. Acho que preciso usar o @Produces, para produzir minha unidade de persistência, mas não achei uma maneira de criar a unidade personalizada para cada conexão, cada uma com seu jta-data-source.

Esse código funciona perfeitamente:


@Dependent
public class ApplicationConfig implements Serializable {

    @Produces
    @PersistenceUnit(unitName = "UnidadePersistenciaPU")
    @EntityManagerConfig
    public EntityManagerFactory emf;

    @Produces
    @EntityManagerConfig
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }
}

Mas o problema é que a unidade de persistência “UnidadePersistenciaPU” tem um jta-data-source fixo no arquivo, e não sei em qual momento eu poderia mudar esse valor. Eu poderia criar um arquivo xml para cada cliente, e depois uma atributo EntityManagerFactory para cada cliente, mas também precisaria recompilar a aplicação a cada novo cliente cadastrado.

Também tentei deixar o metodo que produz dessa maneira:

@Produces
@EntityManagerConfig
public EntityManager getEntityManager() {=       
     EntityManagerFactory emf = Persistence.createEntityManagerFactory("UnidadePersistenciaPU");
     return emf.createEntityManager();
}

Mas assim é lançado o seguinte erro:

Qual a solução para esse problema?

Desde já agradeço!

Tudo bom Ricardo?
Vc conseguiu resolver este problema?
Se sim, poderia compartilhar qual foi a solução?
Obrigado.

Opa, tudo certo. Na verdade não como eu queria. Até dei um tempo nesse assunto, mas ainda procuro a solução que quero. Encontrei essa solução, que se encaixaria no problema:

http://luisfelipevs.wordpress.com/2010/08/10/alterando-opcoes-do-persistence-xml-dinamicamente/

Mas com ela, tive problemas no controle de transação do glassfish, pois estou usando JTA.

A única coisa que deu certo foi o que comentei no pots, criando um atributo para cada Unidade de Persistente no @Produces, mais ou menos assim.


   @PersistenceContext(unitName = "PU1", type = PersistenceContextType.EXTENDED)
    private EntityManager entityManager;
    @PersistenceContext(unitName = "PU2", type = PersistenceContextType.EXTENDED)
    private EntityManager entityManager2;
    @Resource
    private SessionContext sessionContext;

    @Produces
    @RequestScoped
    @EntityManagerConfig    //Anotação personalizada
    public EntityManager getEntityManager() {

        String userName = sessionContext.getCallerPrincipal().getName();
        if("ricardo".equals(userName)){
             return entityManager;
        }else{
             return entityManager2;
        }
     }

Mas essa solução é pouco funcional, pois depende da recomplilação da app.

Obrigado Ricardo.
Faço exatamente como vc faz. Um método para retornar o EntityManager selecionado.
Mas fiquei com uma dúvida no seu código.
Pq vc usa o @Produces?
E pq PersistenceContextType.EXTENDED? Vc usa stateful beans?
E eu criei um novo post sobre isso nesse link: http://www.guj.com.br/java/274725-ejb3---criando-entitymanagers-dinamicamente-pegando-informacoes-da-base-de-dados-por-examplo
Vai acompanhando que talvez alguém nos ajude a achar a solução.
T+

Olá jaabax,

Como eu uso CDI para injeção do EntityManager nos beans, tive que customizar o metodo produtor da injeção, por isso o @Produces. E sim, uso um stateful bean, caso contrario tenho problemas com lazy load. Vou acompanhar o novo tópico sim, vlw!