Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Configurar o persistence.xml para acessar o mesmo BD, porém com usuarios diferentes

Bom dia pessoal!

No meu BD Oracle, eu possuo "um" database, porém algumas tabelas foram criadas com o "usuario1" e outras tabelas com o "usuario2". Olhei no blog da Caelum e ví um post para acessar dois BD distintos, tentei adaptar para meu caso... Porém no persistence.xml gera um alerta:

Multiple persistence units defined - only the first persistence unit will be recognized

Alterei o persistence.xml para:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">
    <persistence-unit name="usuario1">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/usuario1DS</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
            <property name="hibernate.connection.url" value="jdbc:oracle:thin:@ipDoServidor:1521/meuDB" />
            <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" />
            <property name="hibernate.connection.username" value="usuario1" />
            <property name="hibernate.connection.password" value="senhaBD" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <!-- OPCIONAIS -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
        </properties>
    </persistence-unit>

    <persistence-unit name="ebfmes">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/usuario2DS</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
            <property name="hibernate.connection.url" value="jdbc:oracle:thin:@ipDoServidor:1521/meuBD" />
            <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" />
            <property name="hibernate.connection.username" value="usuario2" />
            <property name="hibernate.connection.password" value="senhaBD" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <!-- OPCIONAIS -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
        </properties>
    </persistence-unit>
</persistence>

Criei a anotação para o usuario1:

package br.com.empresa.infra;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@Qualifier
public @interface Usuario1 {
}

Criei a anotação para o usuario2:

package br.com.empresa.infra;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@Qualifier
public @interface Usuario2 {
}

Alterei meu JPAUtil (EntityManagerProducer), para:

package br.com.empresa.infra;

import java.io.Serializable;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;

@ApplicationScoped
public class JPAUtil implements Serializable {

    private static final long serialVersionUID = 1L;

    @PersistenceUnit(unitName = "usuario1")
    private EntityManagerFactory usuario1Factory;

    @PersistenceUnit(unitName = "usuario2")
    private EntityManagerFactory usuario2Factory;

    // @Produces => Para informar ao CDI que esse será o método utilizado para criar as E.M.
    // @RequestScoped => Para criar um E.M. por requisição WEB.

    @Produces
    @Usuario1
    @RequestScoped
    public EntityManager createUsuario1EntityManager() {
        return usuario1Factory.createEntityManager();
    }

    @Produces
    @Usuario2
    @RequestScoped
    public EntityManager createUsuario2EntityManager() {
        return usuario2Factory.createEntityManager();
    }

    // @Disposes => Para informar ao CDI que esse será o método que fecha o E.M.
    public void close(@Disposes EntityManager manager) {
        if (manager.isOpen()) {
            manager.close();
        }
    }
}

E adicionei a anotação no ProdutoDao a anotação do usuario1, pois essa tabela foi criada com esse usuario:

    @Inject
    public ProdutoDao(@Usuario1 EntityManager manager) {
        this.manager = manager;
    }
5 respostas

Ao tentar acessar a lista de produtos, gera o erro no browser:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error that prevented it from fulfilling this request.

exception

java.lang.NullPointerException
    br.com.ebf.infra.JPAUtil.createUsuario1EntityManager(JPAUtil.java:32)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)

A linha 32 no JPAUtil é:

return usuario1Factory.createEntityManager();

Se vc não tiver usando um servidor de aplicação, essa annotation @PersistenceUnit só funciona dentro de um desses... Wildfly etc. Caso não esteja, vc vai precisar escrever o código que cria uma EntityManagerFactory. Lembra, se ta dando NPE é pq aquela variável ta nula, ou seja, nada foi injetado.

Então Alberto, eu estou utilizando o Tomcat 8.5...

No outro projeto, eu estava acessando somente, as tabelas do "usuario1"...

Então o JPAUtil estava:

package br.com.ebf.infra;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

@ApplicationScoped
public class JPAUtil {

    private EntityManagerFactory factory = Persistence.createEntityManagerFactory("default");

    // @Produces => Para informar ao CDI que esse será o método utilizado para criar as E.M.
    // @Produces => Para criar um E.M. por requisição WEB.
    @Produces
    @RequestScoped
    public EntityManager getEntityManager() {
        return factory.createEntityManager();
    }

    // @Disposes => Para informar ao CDI que esse será o método que fecha o E.M.
    public void close(@Disposes EntityManager manager) {
        manager.close();
    }
}

E o persistence.xml "padrão"...

solução!

Então, como eu falei, não vai funcionar. Vc tem que pegar esse código que mostrou agora e adaptar para a sua situação. Basicamente duplicar a linha de criação do EntityManagerFactory.

Mantive a implementação do persistence.xml e duas anotações como eu havia postado... E na primeira implementação do JPAUtil, alterei as linhas conforme vc me orientou... Perfeito!!

Obrigado!!