Hibernate Loader减慢了Hibernate SqlQuery

时间:2016-02-10 11:48:41

标签: java sql performance hibernate db2

我在使用DB2数据库的Hibernate 3.6.9 Final下的SqlQuery中表现不佳。 sql是从SQL客户端(Squirrel)快速制作的:

Query 1 of 1, Rows read: 175, Elapsed time (seconds) - Total: 0.527, SQL query: 0.233, Reading results: 0.29

我使用的是自己的ResultTransformer,但它工作得很好而且很快(我测量了时间)。

我一直在寻找时间,我发现当org.hibernate.loader.Loader对其方法进行一些调用时,所有时间(大约12秒!!!)都会丢失:

11:21:17,026 DEBUG 127.0.0.1 -  MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[426] - about to open ResultSet (open ResultSets: 0, globally: 0)
11:21:17,205 DEBUG 127.0.0.1 - MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row: 
11:21:17,272 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row: 

...175 rows all the same...

11:21:27,978 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row: 
11:21:28,037 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row: 
11:21:28,096 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[433] - about to close ResultSet (open ResultSets: 1, globally: 1)
11:21:28,097 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[418] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)

正如您在左侧的日志中看到的那样,花费了大约11秒。我在这个Hibernate类上搜索了一下,在这里找到了源代码:http://goo.gl/6oAXLT并且得出结论:Loader中的getRow()方法每行进行1次查询(总计:175次)以便对ID进行检查等等on,但我不知道如何禁用此行为,或者我应该修改哪些配置以避免此延迟。

我的映射是:

主要对象(请求):

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.enterprise.myappweb.model.requests.request.Request" 
        table="REQUEST" schema="${db2.app.schema}">
        <id name="id" type="java.lang.Long" access="field">
            <column name="REQUEST_ID" />
            <generator class="native" />
        </id>

        <property name="name" type="java.lang.String">
            <column name="NAME" not-null="true" />
        </property>

        <property name="description" type="java.lang.String">
            <column name="DESCRIPTION" not-null="true" />
        </property>

        <property name="improvement" type="java.lang.String">
            <column name="BENEFIT" not-null="true" />
        </property>

        <property name="startScheduledDate" type="java.util.Date">
            <column name="START_SCHEDULED_DATE" not-null="false" />
        </property>

        <property name="createTimestamp" type="java.sql.Timestamp">
            <column name="CREATE_DATE" not-null="true" />
        </property>

        <property name="createUser" type="java.lang.String">
            <column name="CREATE_USER" not-null="true" />
        </property>           
    </class>

    <!-- I omit the named SQL queries here -->
</hibernate-mapping>

紫胶

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.enterprise.myappweb.model.requests.lac.Lac" 
        table="REQUEST_ENTERPRISE_AREA" schema="${db2.app.schema}">
        <composite-id name="id"
            class="com.enterprise.myappweb.model.requests.lac.LacId">
            <key-property name="requestId" type="java.lang.Long">
                <column name="REQUEST_ID" not-null="true" />
            </key-property>
            <key-property name="lacId" type="java.lang.Integer">
                <column name="ENTERPRISE_AREA_ID" not-null="true" />
            </key-property>
        </composite-id>               

        <property name="order" type="java.lang.Integer">
            <column name="ORDER" not-null="true" />
        </property>

        <property name="startScheduledDate" type="java.util.Date">
            <column name="START_SCHEDULED_DATE" not-null="false" />
        </property>

        <property name="finalScheduledDate" type="java.util.Date">
            <column name="END_SCHEDULED_DATE" not-null="false" />
        </property>           
    </class>

    <!-- I omit the named SQL queries here -->
</hibernate-mapping>

PriorityType

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.enterprise.myappweb.model.requests.type.PriorityType" 
        table="PRIORITY_TYPE_REQUEST" schema="${db2.app.schema}">       
        <id name="id" type="java.lang.Short" access="field">
            <column name="PRIORITY_TYPE_REQUEST_ID" />
            <generator class="native" />
        </id>

        <property name="description" type="java.lang.String">
            <column name="DESCRIPTION" not-null="true" />
        </property>                    
    </class>

    <!-- I omit the named SQL queries here -->
</hibernate-mapping>

状态

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.enterprise.myappweb.model.requests.type.Status" 
        table="REQUEST_STATUS" schema="${db2.app.schema}">       
        <id name="id" type="java.lang.Short" access="field">
            <column name="REQUEST_STATUS_ID" />
            <generator class="native" />
        </id>

        <property name="description" type="java.lang.String">
            <column name="DESCRIPTION" not-null="true" />
        </property>                    
    </class>

    <!-- I omit the named SQL queries here -->
</hibernate-mapping>

的RequestType

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.enterprise.myappweb.model.requests.type.RequestType" 
        table="REQUEST_TYPE_REQUEST" schema="${db2.app.schema}">       
        <id name="id" type="java.lang.Short" access="field">
            <column name="REQUEST_TYPE_REQUEST_ID" />
            <generator class="native" />
        </id>

        <property name="description" type="java.lang.String">
            <column name="DESCRIPTION" not-null="true" />
        </property>                    
    </class>

    <!-- I omit the named SQL queries here -->
</hibernate-mapping>

Java代码:

@Repository("requestDao")
public class RequestDaoHibernate extends AbstractReadWriteDao<Request, Long> implements RequestDao {
    @Override
    public List<Request> findRequests(final RequestSearchDto requestSearchDto, final Boolean isWarehouseUser) {
        queryString = "SELECT .... FROM ...."; // Long string
        List<Request> result = this.listSQLQuery(queryString.toString(), new SQLQueryCallback() {
            @Override
            public void doWithQuery(final SQLQuery query) {
                // Recuperamos idiomas (del usuario y por defecto) a través de spring
                String idiom = LocaleContextHolder.getLocale().getLanguage().toUpperCase();
                query.setParameter("isoCodeLanguageId", 3);
                query.setParameter("defaultLanguageId", 1);

                for(Entry<String, Object> e : dictionary.entrySet()) {
                    if(e.getKey().endsWith("List")) {
                        query.setParameterList(e.getKey(), (Collection)e.getValue());
                    } else {
                        query.setParameter(e.getKey(), e.getValue());
                    }
                }

                RequestSearchRT rt = new RequestSearchRT();

                query.setResultTransformer(rt);
            }});

            return result;
        }
    }

    SuppressWarnings({"unchecked"})
    public <S> List<S> listSQLQuery(final String sqlQuery,
            final SQLQueryCallback callback) {

        if (LOG.isDebugEnabled()) {
            LOG.debug("Listing elements with SQL query: {}", sqlQuery);
        }

        return (List<S>) getHibernateTemplate().execute(new HibernateCallback() {

            @Override
            public List<S> doInHibernate(final Session session) throws SQLException {
                SQLQuery query = session.createSQLQuery(sqlQuery);

                callback.doWithQuery(query);

                return query.list();
            }
        });
    }
}

我会按照人们问我的配置设置更新帖子,因为我认为所有配置都在几个文件中并且很大。

提前致谢。

0 个答案:

没有答案