Problema crítico com performance - JSF - HIBERNATE(JPA) + SPRING

Pessoal to com um problema seríssimo de performance numa aplicação utilizando JSF - HIBERNATE(JPA) + SPRING.
Resumindo o que acontece é o seguinte:

Toda funcionalidade estão funcionando. O problema é: toda vez que eu clico num link, menu, commandLink, commandButton, não IMPORTA onde, um clique apenas, (mesmo que seja uma simples navegaçao de uma pagina pra outra sem precisar nenhum procedimento demorado) TODAS minhas classes que estão mapeadas pro banco com annotations são compiladas novamente, e não apenas compiladas, fico observando na saída do conteiner após clicar, as vezes são compiladas de 5 a 10 vezes as mesmas classes, depois disso ai sim vai pra página que deveria ir, isso acontece pra TODOS cliques, ações etc…

A unidade de persistência foi criada pelo netbeans em gerar unidade pela tabela do banco, pra ele gerar anotações automáticas.

Vejam aqui a saída, tirei parte das classes pois são muitas, mas compila todas elas, esse código abaixo se repete em torno de 5 a 10 vezes a cada clique/ação…


INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
04/03/2008 10:25:09 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@8a9d2a]: org.springframework.beans.factory.support.DefaultListableBeanFactory@15fc606
04/03/2008 10:25:09 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from class path resource [jdbc.properties]
04/03/2008 10:25:09 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'org.springframework.aop.config.internalAutoProxyCreator' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
04/03/2008 10:25:09 com.mchange.v2.log.MLog <clinit>
INFO: MLog clients using java 1.4+ standard logging.
04/03/2008 10:25:09 com.mchange.v2.c3p0.C3P0Registry banner
INFO: Initializing c3p0-0.9.1.1 [built 15-March-2007 01:32:31; debug? true; trace: 10]
04/03/2008 10:25:09 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'dataSource' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
04/03/2008 10:25:09 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter#1da366c' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
04/03/2008 10:25:10 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean createNativeEntityManagerFactory
INFO: Building JPA container EntityManagerFactory for persistence unit 'VirtualProjectNegocioPU'
04/03/2008 10:25:10 org.hibernate.cfg.annotations.Version <clinit>
INFO: Hibernate Annotations 3.3.0.GA
04/03/2008 10:25:10 org.hibernate.cfg.Environment <clinit>
INFO: Hibernate 3.2.5
04/03/2008 10:25:10 org.hibernate.cfg.Environment <clinit>
INFO: hibernate.properties not found
04/03/2008 10:25:10 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: Bytecode provider name : cglib
04/03/2008 10:25:10 org.hibernate.cfg.Environment <clinit>
INFO: using JDK 1.4 java.sql.Timestamp handling
04/03/2008 10:25:10 org.hibernate.ejb.Version <clinit>
INFO: Hibernate EntityManager 3.3.1.GA
04/03/2008 10:25:10 org.hibernate.ejb.Ejb3Configuration configure
INFO: Processing PersistenceUnitInfo [
        name: VirtualProjectNegocioPU
        ...]
04/03/2008 10:25:10 org.hibernate.ejb.Ejb3Configuration scanForClasses
INFO: found EJB3 Entity bean: com.virtual.Model.Aquisicao
04/03/2008 10:25:10 org.hibernate.ejb.Ejb3Configuration scanForClasses
INFO: found EJB3 Entity bean: com.virtual.Model.Artefato
04/03/2008 10:25:10 org.hibernate.ejb.Ejb3Configuration scanForClasses
INFO: found EJB3 Entity bean: com.virtual.Model.Assinatura
04/03/2008 10:25:10 org.hibernate.ejb.Ejb3Configuration scanForClasses
INFO: found EJB3 Entity bean: com.virtual.Model.Atividade

// AQUI TEM MAIS UMAS 40 CLASSES AINDA.....

// DEPOIS QUE TERMINA sacnForClasses para todas ele começa a fazer um bindTable pra todas

04/03/2008 10:25:12 org.hibernate.cfg.AnnotationBinder bindClass
INFO: Binding entity from annotated class: com.virtual.Model.Assinatura
04/03/2008 10:25:12 org.hibernate.cfg.annotations.EntityBinder bindTable
INFO: Bind entity com.virtual.Model.Assinatura on table assinatura
04/03/2008 10:25:12 org.hibernate.cfg.AnnotationBinder bindClass
INFO: Binding entity from annotated class: com.virtual.Model.PerfilFase
04/03/2008 10:25:12 org.hibernate.cfg.annotations.EntityBinder bindTable
INFO: Bind entity com.virtual.Model.PerfilFase on table perfil_fase
04/03/2008 10:25:12 org.hibernate.cfg.AnnotationBinder bindClass
INFO: Binding entity from annotated class: com.virtual.Model.TipoFluxo
04/03/2008 10:25:12 org.hibernate.cfg.annotations.EntityBinder bindTable

//AQUI TEM MAIS UMAS 40 CLASSES fazendo essa bindTable

//AQUI O RESTO DA SAÍDA
INFO: Default entity-mode: pojo
04/03/2008 10:25:16 org.hibernate.cfg.SettingsFactory buildSettings
INFO: Named query checking : enabled
04/03/2008 10:25:16 org.hibernate.impl.SessionFactoryImpl <init>
INFO: building session factory
04/03/2008 10:25:17 org.hibernate.impl.SessionFactoryObjectFactory addInstance
INFO: Not binding factory to JNDI, no JNDI name configured

E toda essa saída ocorre de 5 a 10 vezes em CADA clique/solicitação

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" 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_1_0.xsd">
  <persistence-unit name="VirtualProjectNegocioPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>com.virtual.Model.Assinatura</class>
    <class>com.virtual.Model.PerfilFase</class>
  // MAIS CLASSES AQUI....
 <properties>
      <property name="hibernate.connection.username" value="postgres"/>
      <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
      <property name="hibernate.connection.password" value="virtual"/>
      <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/virtualhomologacao"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
    </properties>
  </persistence-unit>

application-context.xml[code]





<!-- Local C3P0 DataSource que trabalha em qualquer ambiente -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!-- JPA EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true"/>
            <property name="generateDdl" value="false"/>
            <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
        </bean>
    </property>
</bean>

<!-- Transaction manager para um JPA EntityManagerFactory simples (alternativa ao JTA) -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- Instrui o Spring a realizar gerenciamento transacional declarativo automático nas classes anotadas.-->
<tx:annotation-driven/>

<!-- PostProcessors para realizar injeção de recursos de acordo com a especificação JPA (@PersistenceContext, @PersistenceUnit). -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

<!-- PostProcessors para realizar a conversão de exceções nas classes @Repository (das exceções nativas como JPA PersistenceExceptions to Spring's DataAccessException). -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
[/code]

Se alguém já passou por isso e puder ajudar…

Buntu, bom dia!

Estou dando um tiro no escuro, mas puxando a bagaça pro lado do Hibernate…

Por algum acaso vc não está criando várias SessionFactory sem necessidade? Ao Invés de Criar uma e trabalhar com objetos Session? :shock:

Criar SessionFactory é um processo muito custoso… espero que tenha ajudado! :wink:

estou usando o entityManagerFactory como está no application-context, configurei com JNDI e a cargo do conteiner as conexões…porém continuo com o problema…caso alguém ajude…vlw…

Cara que problema bizarro…

Você tá colocando alguma lógica de acesso a banco nos metodos getters dos managed beans?
Pergunto porque os getters são invocados várias vezes durante o ciclo de vida da requisição…

agora, pra rolar o binding com as tabelas todas as vezes que vc envia uma requisição, pode ser que um método getter esteja criando o EMF. É a única razão que consigo pensar agora…

muito estranho

[quote=Ferryman]Cara que problema bizarro…

Você tá colocando alguma lógica de acesso a banco nos metodos getters dos managed beans?
Pergunto porque os getters são invocados várias vezes durante o ciclo de vida da requisição…

agora, pra rolar o binding com as tabelas todas as vezes que vc envia uma requisição, pode ser que um método getter esteja criando o EMF. É a única razão que consigo pensar agora…

muito estranho[/quote]

pior que não… não uso no get… as vezes é uma simples navegação pelo faces-config ele percorre as classes varias vezes…mesmo que ela nao busque dados no banco…to louco com isso… :cry:

Ola Javabuntu,

Estou passando por um problema muito parecido com o seu… estou usando os mesmos frameworks e meu site tem algumas áreas com bastante acesso e que necessitam de fazer consultas ao banco.
Vc conseguiu resolver esse problema?

Dede já agradeço a atenção.

[/code][quote=thiago-hc]Ola Javabuntu,

Estou passando por um problema muito parecido com o seu… estou usando os mesmos frameworks e meu site tem algumas áreas com bastante acesso e que necessitam de fazer consultas ao banco.
Vc conseguiu resolver esse problema?

Dede já agradeço a atenção.[/quote]

Thiago, resolvi…
meu maior problema foi com JSF a performance.
Meu projeto estava assim: um UsuarioBean, que era um managed-bean declarado no faces, e nele eu tinha meus métodos, minhas propriedades ligadas nas telas pelo binding… não sei porque, mesmo não tendo lógica nos getters, parece que executava TUDO que tinha naquele bean…

o que fiz:

para CADA bean, criei uma action, UsuarioAction e UsuarioBean, e no faces config eu declarava o UsuárioBean como uma propriedade do UsuarioAction…

o que ficava no UsuarioBean:

public class UsuarioBean{
    // todas minhas propriedades com getters e setters e NADA mais
}

na minha action:

public class UsuarioAction{
     private UsuarioBean userBean; 
     // veja que aqui eu tenho uma propriedade bean dentro da action
    // Aqui na action coloquei todos meu métodos de controle e NENHUMA propriedade com binding na tela
}
 

nas minhas telas, os valores era sempre ligados assim:

//Veja que uso a action pra ligar no bean
&lt;h:outPutTex   value="usuarioAction.userBean.nome"

&gt;&lt;h:commandButton action="usuarioAction.FazAlgo"

basicamente esse processo resolveu meu problema que estava terrível…
o porque que resolveu não sei exatamente, mas pelo jeito sempre ia no bean que tinha os binding, ele parecia executar o bean inteiro, e deixei com scopo de session só necessário do necessário mesmo.

flw Hewerton>