我已经调试了一些我没写的hibernate代码。我会直截了当地承认,我很难理解Hibernate如何将查询汇总到这一点,所以请耐心等待。
我们看到的问题是Web应用程序花费了大量时间来加载页面(使用JSP,Spring和Hibernate)。
正在执行的查询之一引用了一个似乎在hibernate执行的查询中使用了两次的映射的公式。第一个引用是列值,第二个引用用作内连接的条件。内连接中的第二个是强制执行我们不需要的全表扫描,更不用说它使查询真的很慢。
有没有办法调整hibernate查询,以便它不在查询中使用此公式(列值除外)?如果您需要更多信息,请告知。
编辑:根据要求,这是我从日志记录中获取的查询:
SELECT this_.PARTY_ID AS PARTY1_23_2_,
this_.STUDENT_ID AS STUDENT3_23_2_,
this_.STUDENT_PIDM AS STUDENT4_23_2_,
this_.USERNAME AS USERNAME23_2_,
this_.FIRST_NAME AS FIRST6_23_2_,
this_.LAST_NAME AS LAST7_23_2_,
this_.ACTIVE AS ACTIVE23_2_,
subjectenr1_.PARTY_ID AS PARTY1_24_0_,
subjectenr1_.OFFERING_ID AS OFFERING2_24_0_,
subjectenr1_.RSTS_CODE AS RSTS3_24_0_,
subjectenr1_.SITE_CODE AS SITE4_24_0_,
subjectenr1_.PROGRAM_CODE AS PROGRAM5_24_0_,
(SELECT su2.offering_id
FROM sakaicfg.subject_offering su2
WHERE su2.offering_id = subjectenr1_.OFFERING_ID
) AS formula0_0_,
subjectoff2_.OFFERING_ID AS OFFERING1_25_1_,
subjectoff2_.CRN AS CRN25_1_,
subjectoff2_.IS_ACTIVE AS IS3_25_1_,
subjectoff2_.TEACHING_SCHOOL AS TEACHING4_25_1_,
subjectoff2_.CAMPUS AS CAMPUS25_1_,
subjectoff2_.START_SEMESTER AS START6_25_1_,
subjectoff2_.STUDYMODE AS STUDYMODE25_1_,
subjectoff2_.SUBJECT_ID AS SUBJECT8_25_1_,
subjectoff2_.GRADE_MARKING_CODE AS GRADE9_25_1_,
(SELECT MAX(su2.effective_semester)
FROM sakaicfg.subject su2
WHERE su2.subject_id = subjectoff2_.SUBJECT_ID
AND su2.effective_semester <= subjectoff2_.START_SEMESTER
) AS formula1_1_
FROM SAKAICFG.STUDENT this_
INNER JOIN SAKAICFG.SUBJECT_ENROLMENT subjectenr1_
ON this_.PARTY_ID=subjectenr1_.PARTY_ID
INNER JOIN SAKAICFG.SUBJECT_OFFERING subjectoff2_
ON (SELECT su2.offering_id
FROM sakaicfg.subject_offering su2
WHERE su2.offering_id = subjectenr1_.OFFERING_ID)=subjectoff2_.OFFERING_ID
WHERE this_.ACTIVE ='Y'
AND subjectenr1_.RSTS_CODE <>'DD'
AND subjectoff2_.IS_ACTIVE ='Y'
AND subjectoff2_.OFFERING_ID='35505'
ORDER BY this_.PARTY_ID DESC;
有问题的部分是摘录:
(SELECT su2.offering_id
FROM sakaicfg.subject_offering su2
WHERE su2.offering_id = subjectenr1_.OFFERING_ID
)
Subject Enrollment表的映射xml文件包含以下关系:
<many-to-one name="student" entity-name="CsuActiveStudentDto" column="PARTY_ID" insert="false" update="false" access="field" unique="false"/>
<many-to-one name="subjectOffering" entity-name="CsuSubjectOfferingDto" insert="false" update="false" access="field" unique="false">
<formula>(select su2.offering_id
from sakaicfg.subject_offering su2 where su2.offering_id = OFFERING_ID)</formula>
</many-to-one>
<one-to-one name="student" class="au.edu.csu.enterprise.domain.StudentDto" property-ref="enrolment"/>
<many-to-one name="offering" class="au.edu.csu.enterprise.domain.SubjectOfferingDto" column="OFFERING_ID"/>
我一直在与我们的DBA一起工作,查看查询并隔离需要查看的查询,这就是我们找到这个查询的方式。
答案 0 :(得分:0)
您可以通过自定义SQL(而不是hql)为每个实体(以及集合)覆盖Hibernate Create Read Update和Delete语句。
有关更多详细信息,请参阅Hibernate Reference:Chapter 17.3. Custom SQL for create, update and delete以及它在Hibernate Annotation Reference中的工作原理:Chapter 2.4.10. Custom SQL for CRUD operations
@Entity
@SQLInsert( sql="INSERT INTO Demo(name, id) VALUES(?,?)")
@Loader(namedQuery = "betterLoad")
@NamedNativeQuery(name="betterLoad",
query="select id, name from Demo where id= ?",
resultClass = Demo.class)
public class Demo {
@Id
private Long id;
private String name;
}