Motivo da demora do processo e configuração do hibernate (persistence)

Estou montando um servidor WS com Java, e estou vendo algumas problemas, como o login via POSTMAN, está demorando entre 6000 a 7500 ms para responder, sendo o que ele realmente faz, é de em torno 50 ms. Após conseguir configurar o log4, a maior parte da demora está em:

org.hibernate.dialect.Dialect até org.hibernate.jpa.internal.util.LogHelper

Segue abaixo todo o stack do log:

018-01-31 14:21:38 INFO  org.hibernate.jpa.internal.util.LogHelper     - HHH000204: Processing PersistenceUnitInfo [
    name: persistence_unit_meudb
    ...]
2018-01-31 14:21:38 WARN  org.hibernate.orm.connections     - HHH10001002: Using Hibernate built-in connection pool (not for production use!)
2018-01-31 14:21:38 INFO  org.hibernate.orm.connections     - HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/meudb]
2018-01-31 14:21:38 INFO  org.hibernate.orm.connections     - HHH10001001: Connection properties: {user=root, password=****}
2018-01-31 14:21:38 INFO  org.hibernate.orm.connections     - HHH10001003: Autocommit mode: false
2018-01-31 14:21:38 INFO  org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl     - HHH000115: Hibernate connection pool size: 20 (min=1)
2018-01-31 14:21:38 INFO  org.hibernate.dialect.Dialect     - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
2018-01-31 14:21:42 INFO  org.hibernate.jpa.internal.util.LogHelper     - HHH000204: Processing PersistenceUnitInfo [
    name: persistence_unit_meudb
    ...]
2018-01-31 14:21:42 WARN  org.hibernate.orm.connections     - HHH10001002: Using Hibernate built-in connection pool (not for production use!)
2018-01-31 14:21:42 INFO  org.hibernate.orm.connections     - HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/meudb]
2018-01-31 14:21:42 INFO  org.hibernate.orm.connections     - HHH10001001: Connection properties: {user=root, password=****}
2018-01-31 14:21:42 INFO  org.hibernate.orm.connections     - HHH10001003: Autocommit mode: false
2018-01-31 14:21:42 INFO  org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl     - HHH000115: Hibernate connection pool size: 20 (min=1)
2018-01-31 14:21:42 INFO  org.hibernate.dialect.Dialect     - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
2018-01-31 14:21:45 WARN  org.hibernate.jpa.internal.EntityManagerFactoryRegistry     - HHH000436: Entity manager factory name (persistence_unit_meudb) is already registered.  If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'
Antes do Try: 2018-01-31 14:21:45.345
2018-01-31 14:21:45 INFO  org.hibernate.hql.internal.QueryTranslatorFactoryInitiator     - HHH000397: Using ASTQueryTranslatorFactory
Hibernate: 
    select
        [ Campos ]
    from
        tbusuario usuario0_ 
    where
        usuario0_.login=? 
Antes do Return: 2018-01-31 14:21:45.387
2018-01-31 14:21:45 INFO  org.hibernate.orm.connections     - HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/meudb]
2018-01-31 14:21:45 INFO  org.hibernate.orm.connections     - HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/meudb]
Antes do Return: 2018-01-31 14:21:45.389

Gostaria de saber se há alguma configuração a se fazer no persistence ou biblioteca que deixe esse processo mais rápido.

Segue o meu 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_meudb" transaction-type="RESOURCE_LOCAL">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <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/meudb"/>
         <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>

Hibernate é custoso mesmo, principalmente a inicialização qué uma bomba, teria que deixar essa bomba na memória da aplicação para ser reutilizada, enfim vai consumir mais recursos. Qual necessidade de usar Hibernate, ainda mais em um webservice?

Tem alguma maneira de implementar JPA/Persistence por entidade sem hibernate ?

Exemplo de modelo:

@Entity
@Table(name = "tbusuario")
public class Usuario {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "nrseq")
	private int nrseq;

	@Column(name = "nome")
	private String nome;

	@ManyToOne
	@JoinColumn(name = "permissao")
	private Permissao permissao;

Exemplo da persistencia:

try {
			this.entityManager.getTransaction().begin();
			this.entityManager.persist(gas);
			this.entityManager.getTransaction().commit();
		} catch (Exception e) {
			System.out.println(sj.getFullStackTrace(e));
			
		}

Não precisa se prender a JPA, todas as implementacoes de JPA são custosas.

Quantas entidades tem nesse web service? Se forem poucas, faz as querys direto via Jdbc.

Um meio termo mais leve para mapear objetos seria usar JdbcTemplate.

43 entidades.
Como poderia deixar na memória o Hibernate ?

Esse webservice poderia ser quebrado em vários por módulos.

Eu usaria JdbcTemplate, mas segue o que pediu:

De qualquer forma a primeira chamada será lenta.

E como faria para meu código utilizar esta conexão ?
Atualmente ele faz da seguinte forma.
Quando o controlador da um new, ele faz esse construtor:

	private final EntityManagerFactory entityManagerFactory;
	
	private final EntityManager entityManager;
	
	SmartJava sj = new SmartJava();
	
	public UsuarioDAO() {
		this.entityManagerFactory = Persistence.createEntityManagerFactory("persistence_unit_souvizinho");
		this.entityManager = this.entityManagerFactory.createEntityManager();
	}

Não é para ser chamado no DAO, crie uma classe só para isso. Segue o exemplo que te passei. createEntityManagerFactory deverá ser chamado uma única vez e a instancia ser armazenada como static, ou seja, ficará na memória enquanto a aplicacao estiver viva. Não sei se isso vai valer para web service, mas já que quer tanto usar JPA, tenta.

Então, mais uma dúvida.

  1. Seria uma classe que eu daria um NEW quando recebe a requisição ?
  2. Ou colocaria isso de alguma maneira, que chamaria apenas ao iniciar a aplicação, e como faria isso, e como passaria isso para o DAO

Segue o exemplo. Pode pesquisar outros relacionados a singleton + jpa + createEntityManagerFactory.

Cria uma classe separada com o código do exemplo e dá o nome de JpaUtil por exemplo. No DAO voce vai chamar JpaUtil.getInstance() do exemplo.

Como fiz:

Classe criada:

private final EntityManagerFactory entityManagerFactory;

private final EntityManager entityManager;

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

public EntityManagerFactory getFactory() {
	return entityManagerFactory;
}

public EntityManager getInstance() {
	return entityManager;
}

public void fechar() {
	if(this.entityManager.isOpen())
		this.entityManager.close();
	if(this.entityManagerFactory.isOpen())
		this.entityManagerFactory.close();
}

Como passo pros meus DAO’s:

private final EntityManagerSingleton singleton = new EntityManagerSingleton();
	private final UsuarioDAO usuarioDAO = new UsuarioDAO(singleton.getFactory(), singleton.getInstance());
	private final outroDAO outroDAO = new outroDAO(singleton.getFactory(), singleton.getInstance());

O tempo foi reduzido pela metade (entre 3200ms a 3800ms)

Ele demora os 3000 ao realizar isto:
2018-02-01 11:14:38 INFO org.hibernate.hql.internal.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory

Debugando, se createEntityManagerFactory for chamado uma única vez na vida da aplicação no ar recebendo várias requisições, é porque deu certo.