2
respostas

Como implementar DataSource em um servidor REST ?

Estou finalizando um projeto que utiliza um servidor REST em Java, e é implementado no Tomcat, e me encontro com um problema, o tempo que o serviço demora para implementar uma nova conexão (de 3000ms a 5000ms) do banco, levando a uma lentidão da aplicação.

Pesquisei e vi algo sobre Datasource (até dei uma olhadas nos cursos), mas não consegui implementar. Tentei de 2 formas:

PS: No caso, seria mais fácil implementar o projeto (e mudar) para o JBOSS (e como fazer), ou tentar implementar com Datasource ?

A primeira vez objetive o erro abaixo:

org.apache.tomcat.dbcp.dbcp2.BasicDataSource cannot be cast to javax.persistence.EntityManagerFactory

Onde chamo o DataSource:

public class EntityManagerSingleton {

    @PersistenceUnit(name="jdbc/dbsouvizinho", unitName="persistence_unit_souvizinho") private EntityManagerFactory entityManagerFactory;
    @PersistenceContext(name="jdbc/dbsouvizinho", unitName="persistence_unit_souvizinho") private EntityManager entityManager;

    public EntityManagerSingleton() {


        try {
            entityManagerFactory = (EntityManagerFactory) new InitialContext().lookup("java:comp/env/jdbc/dbsouvizinho");
            entityManager = (EntityManager) new InitialContext().lookup("java:comp/env/jdbc/dbsouvizinho");
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
public EntityManagerFactory getFactory() {
        return entityManagerFactory;
    }

    public EntityManager getInstance() {
        return entityManager;
    }

Persistence.XML:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
                                http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
             version="2.0" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns="http://java.sun.com/xml/ns/persistence">

   <persistence-unit name="persistence_unit_souvizinho" transaction-type="RESOURCE_LOCAL">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
       <non-jta-data-source>java:/comp/env/jdbc/dbsouvizinho</non-jta-data-source>
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
         <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
         <!--  <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/dbsouvizinho"/>
         <property name="javax.persistence.jdbc.user" value="root"/>
         <property name="javax.persistence.jdbc.password" value="root"/> -->
         <property name="hibernate.show_sql" value="true"/>
         <property name="hibernate.format_sql" value="true"/>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
      </properties>
   </persistence-unit>
</persistence>

WEB.XML

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>br.com.souvizinho.controlador</param-value>

    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/webapi/*</url-pattern>
  </servlet-mapping>
<resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/dbsouvizinho</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
</web-app>

Context (NoProjeto)

<Context>
    <Resource 
        name="jdbc/dbsouvizinho" 
        auth="Container" 
        type="javax.sql.DataSource"
        maxActive="500" 
        maxIdle="100"
        minIdle="100"
        maxWait="10000"
        username="root" 
        password="root"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost/dbsouvizinho/"
    />
</Context>

Imports

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
2 respostas

Na segunda tentativa, o meu factory é nullo (tentando fazer por injenção) Segue abaixo os códigos Singleton(Chamada do DataSource)


    @PersistenceUnit(name="jdbc/dbsouvizinho", unitName="persistence_unit_souvizinho") private EntityManagerFactory entityManagerFactory;
    @PersistenceContext(name="jdbc/dbsouvizinho", unitName="persistence_unit_souvizinho") private EntityManager entityManager;

    public EntityManagerSingleton() {
        //this.entityManagerFactory = Persistence.createEntityManagerFactory("persistence_unit_souvizinho");
        //this.entityManager = this.entityManagerFactory.createEntityManager();
    }

    public EntityManagerFactory getFactory() {
        return entityManagerFactory;
    }

    @RequestScoped
    @Produces
    public EntityManager getInstance() {
        return entityManagerFactory.createEntityManager();
    }

Web.XML

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>br.com.souvizinho.controlador</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/webapi/*</url-pattern>
  </servlet-mapping>


  <resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/dbsouvizinho</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>


  <filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>

Chamando no controlador

this.notificacaoDAO = new NotificacaoDAO(singleton.getInstance());

No DAO


    @Inject
    public NotificacaoDAO(EntityManager instance) {
        this.entityManager = instance;
    }

Minha sugestão: faz o hibernate usar um pool de conexões, o C3P0 por exemplo. Você vai apenas adicionar o jar do pool e configurar o xml informando que você quer usar.