JPA Select query is taking more time - beyond 60 seconds

333 Views Asked by At

Currently we have 45 different tables in DB with 1000 records in each table. Number of parallel requests we get is 15 messages / seconds and each record in table may not exceed 100 KB.

Our situation is that we select the list of tables one after the other with a common id that we have across all the tables ex: emp.id. The select query is based on the emp.id.

When I am firing the select query for all these tables with a specific emp.id, below are the results

  • @ 10 message/second - it is normal and responds back within 500 milliseconds
  • @ 12 message/second- Time is growing continuously and exceeds 60 seconds

What could be going wrong? Also no blocking is identified in DB.

Below is my code

@PersistenceContext
            EntityManager entityManager;// = getEntityManager();

            private EntityManagerFactory entityManagerFactoryNew;//= Persistence.createEntityManagerFactory("srk-orm");
            protected EntityManager getEntityManager() {
                            entityManager = entityManagerFactoryNew.createEntityManager();
                            return entityManager;
            }

            protected void closeEntityManager() {
                            try {
                                            if(null != entityManager) {
                                                            entityManager.close();
                                            }
                            } catch(Throwable th){}
            }


            ////
            private static final Logger LOGGER = LoggerFactory.getLogger(ListActiveEmployeesDAO.class);

            public void setEntityManager(EntityManager entityManager) {
                            this.entityManager = entityManager;
            }


            public List<Employee> getEmployeeDetails(java.lang.Integer EmployeeId) {

                            List<Employee> list=new ArrayList<Employee>();
                            try {



                                            EntityGraph<Employee> EmployeeGraph = entityManager.createEntityGraph(Employee.class);



                                            list =  entityManager.createQuery("SELECT j FROM Employee j "

                                                            + "WHERE j.EmployeeId=:EmployeeId and j.statusCode=:statusCode " , Employee.class)
                                                                            .setParameter("statusCode", 'A')
                                                                            .setParameter("EmployeeId", EmployeeId)
                                                                            .setHint("javax.persistence.fetchgraph", EmployeeGraph)
                                                                            .setLockMode(LockModeType.NONE)
                                                                            .setHint(QueryHints.HINT_READONLY,true)
                                                                            .getResultList();


                                            LOGGER.debug("Employee list size for Single Employee: {}",list.size());








                            } catch(Throwable th) {

                            } finally {
                                            closeEntityManager();
                            }


                            return list;

            }

            public List<EmployeeRoute> getEmployeeRoute(java.lang.Integer EmployeeId){

                            List<EmployeeRoute> list=new ArrayList<EmployeeRoute>();
                            try
                            {
                                            //We will create EntityGraph dynamically
                                            EntityGraph<EmployeeRoute> EmployeeRouteGraph = entityManager.createEntityGraph(EmployeeRoute.class);



                                            list =  entityManager.createQuery("SELECT jr FROM EmployeeRoute jr "

                                                            + "WHERE  jr.Employee.EmployeeId=:EmployeeId AND jr.statusCode=:statusCode  " , EmployeeRoute.class)
                                                                            .setParameter("statusCode", 'A')
                                                                            .setParameter("EmployeeId", EmployeeId)
                                                                            .setHint("javax.persistence.fetchgraph", EmployeeRouteGraph)
                                                                            .setHint(QueryHints.HINT_READONLY,true)
                                                                            .setLockMode(LockModeType.NONE)
                                                                            .getResultList();
                                            LOGGER.debug("EmployeeRoute list size for Single Employee: {}",list.size());



                            } catch(Throwable th) {

                            } finally {
                                            closeEntityManager();
                            }

                            return list;
            }

Below is my applicationContext.xml for JPA.

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" 
       xmlns:task="http://www.springframework.org/schema/task"    
       xmlns:cache="http://www.springframework.org/schema/cache" 
       xsi:schemaLocation="
              http://www.springframework.org/schema/beans   
              http://www.springframework.org/schema/beans/spring-beans.xsd
       
              http://www.springframework.org/schema/tx 
              http://www.springframework.org/schema/tx/spring-tx.xsd
              
              http://www.springframework.org/schema/task
              http://www.springframework.org/schema/task/spring-task.xsd
              
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

       <context:component-scan base-package="com.uil.employee.orm.*" />
       <context:component-scan base-package="com.uil.employee.orm.dao.*" />
       <context:component-scan base-package="com.uil.employee.orm.util.*" />
       <context:component-scan base-package="com.uil.employee.orm.db.*" />
       <!-- <context:property-placeholder location="srk-orm.properties"/> -->
       <context:annotation-config/>
       
       <cache:annotation-driven />
       
       <task:annotation-driven executor="ormTaskExecutor" />
    <task:executor id="ormTaskExecutor" pool-size="${orm.task.executor.initialsize}-${orm.task.executor.maxTotal}" queue-capacity="${orm.task.executor.queueCapacity}" rejection-policy="CALLER_RUNS"/>
       
       <bean
              class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

       <!-- ************ JPA configuration *********** -->
       <tx:annotation-driven transaction-manager="transactionManager" />  
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
        <property name="persistenceUnitName" value="srk-esb-orm" />        
        <property name="dataSource" ref="srkDataSource" />
        <property name="packagesToScan" value="com.uil.employee.orm.*" />
        <!-- JpaVendorAdapter implementation for Hibernate EntityManager.
           Exposes Hibernate's persistence provider and EntityManager extension interface -->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="false" />
                <property name="databasePlatform" value="org.hibernate.dialect.SQLServerDialect" />
                
          
            </bean>
        </property>
              

    </bean>     
    
    <bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
       <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
</beans>

When I run profiler's I see below

    ormTaskExecutor-251  Blocked CPU usage on sample: 0ms
  java.lang.Class.forName0(String, boolean, ClassLoader, Class) Class.java (native)
  java.lang.Class.forName(String, boolean, ClassLoader) Class.java:348
  org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(String) ClassLoaderServiceImpl.java:226
  org.hibernate.internal.util.ReflectHelper.getConstantValue(String, ClassLoaderService) ReflectHelper.java:235
  org.hibernate.hql.internal.ast.QueryTranslatorImpl$JavaConstantConverter.handleDotStructure(AST) QueryTranslatorImpl.java:615
  org.hibernate.hql.internal.ast.QueryTranslatorImpl$JavaConstantConverter.visit(AST) QueryTranslatorImpl.java:610
  org.hibernate.hql.internal.ast.util.NodeTraverser.visitDepthFirst(AST) NodeTraverser.java:60
  org.hibernate.hql.internal.ast.util.NodeTraverser.traverseDepthFirst(AST) NodeTraverser.java:49
  org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(boolean) QueryTranslatorImpl.java:284
  org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(Map, boolean, String) QueryTranslatorImpl.java:187
  org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(Map, boolean) QueryTranslatorImpl.java:142
  org.hibernate.engine.query.spi.HQLQueryPlan.<init>(String, String, boolean, Map, SessionFactoryImplementor, EntityGraphQueryHint) HQLQueryPlan.java:115
  org.hibernate.engine.query.spi.HQLQueryPlan.<init>(String, boolean, Map, SessionFactoryImplementor, EntityGraphQueryHint) HQLQueryPlan.java:81
  org.hibernate.internal.AbstractQueryImpl.applyEntityGraphQueryHint(EntityGraphQueryHint) AbstractQueryImpl.java:1056
  org.hibernate.jpa.internal.QueryImpl.list() QueryImpl.java:604
  org.hibernate.jpa.internal.QueryImpl.getResultList() QueryImpl.java:483
  sun.reflect.GeneratedMethodAccessor565.invoke(Object, Object[])
  sun.reflect.DelegatingMethodAccessorImpl.invoke(Object, Object[]) DelegatingMethodAccessorImpl.java:43
  java.lang.reflect.Method.invoke(Object, Object[]) Method.java:498
  org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(Object, Method, Object[]) SharedEntityManagerCreator.java:362
  com.sun.proxy.$Proxy172.getResultList()

0

There are 0 best solutions below