现在,在一个简短的例子中,如果我有两个实体Person
和Applicant
并且我想编写一个查询来获取我的数据库中的所有申请人,我最终会获得引用查询以下设置。我正在使用Single_Table_Inheritance策略(fyi)
public class Person {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "schoolID")
private School school;
}
带有对另一个实体的引用的Teacher对象。
public class Applicant extends Person {
@OneToMany(targetEntity = ApplicantSchool.class, cascade = { javax.persistence.CascadeType.PERSIST, javax.persistence.CascadeType.REMOVE }, mappedBy = "applicant")
private Set<ApplicantSchool> schools = new HashSet<ApplicantSchool>();
}
跳转并尝试在Person中查询学校关系的查询尝试
public List<Applicant> getAllApplicants(){
EntityManager entityManager = factory.createEntityManager();
@SuppressWarnings("unchecked")
List<Applicant> applicants = entityManager.createQuery("Select a from Applicant a LEFT JOIN FETCH a.schools WHERE a.active = :active ")
.setParameter("active", true).setHint("eclipselink.refresh", "true")
.getResultList();
//List<Applicant> applicants = Applicant.findAllApplicants();
System.out.println("The long query getting applicants");
entityManager.close();
return applicants;
}
如果我尝试更改我的查询以使用嵌套加入,我会收到一条错误,指出关系无法识别。我试着像这样查询:
entityManager.createQuery("Select a from Applicant a LEFT JOIN FETCH a.schools WHERE LEFT JOIN FETCH a.person.school a.active = :active ")
已更新
删除关键字“left join fetch”后,我的新查询:
List<Applicant> applicants = entityManager.createQuery("Select a from Applicant a WHERE a.active = :active ")
.setParameter("active", true)
.getResultList();
我同意的唯一一个问题是它首先创建的是
SELECT personID, TYPE, DATEADDED, FIRSTNAME, LASTNAME, MIDDLENAME, ACTIVE, BIRTHDAY, EMAILADDRESS, ETHNICITY, GENDER, HISPANIC, IMAGEPATH, MARITAL, NATIVELANGUAGE, PRIMARYTELEPHONE, RELIGIOUSAFFILIATION, SECONDARYTELEPHONE, version, addressID, schoolID, MAJOR FROM PERSON WHERE ((ACTIVE = ?) AND (TYPE = ?))
bind => [true, AP]
返回此堆栈跟踪并创建以下sql的选择:
[EL Fine]: sql: 2012-07-13 17:25:52.297--ServerSession(1529073996)--Connection(726700617)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT schoolID, ACTIVE, ADMISSIONSEMAILADDRESS, ADMISSIONSPHONE, CODE, description, HELPGENERALEMAILADDRESS, NAME, PRIMARYPHONE, version, addressID FROM SCHOOL WHERE (schoolID = ?)
bind => [1]
[EL Fine]: sql: 2012-07-13 17:25:52.305--ServerSession(1529073996)--Connection(1615948530)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT id, ACTIVE, CODE, DESCRIPTION, NAME, version, SCHOOLDEPARTMENT_schoolID FROM DEPARTMENT WHERE (SCHOOLDEPARTMENT_schoolID = ?)
bind => [1]
[EL Fine]: sql: 2012-07-13 17:25:52.308--ServerSession(1529073996)--Connection(893810654)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT programID, ACTIVE, CODE, description, NAME, PROGRAMTYPE, REQUIREDCREDITS, version, SCHOOL_schoolID FROM PROGRAM WHERE (SCHOOL_schoolID = ?)
bind => [1]
[EL Fine]: sql: 2012-07-13 17:25:52.31--ServerSession(1529073996)--Connection(399107363)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT personID, TYPE, DATEADDED, FIRSTNAME, LASTNAME, MIDDLENAME, ACTIVE, BIRTHDAY, EMAILADDRESS, ETHNICITY, GENDER, HISPANIC, IMAGEPATH, MARITAL, NATIVELANGUAGE, PRIMARYTELEPHONE, RELIGIOUSAFFILIATION, SECONDARYTELEPHONE, version, addressID, schoolID, MAJOR, studentId FROM PERSON WHERE (schoolID = ?)
bind => [1]
[EL Fine]: sql: 2012-07-13 17:25:52.314--ServerSession(1529073996)--Connection(464642021)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT registrationId, SEMESTERTYPE, version, YEAR, semesterCourseId, personID FROM REGISTRATION WHERE (personID = ?)
bind => [501]
[EL Fine]: sql: 2012-07-13 17:25:52.322--ServerSession(1529073996)--Connection(395757277)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT registrationId, SEMESTERTYPE, version, YEAR, semesterCourseId, personID FROM REGISTRATION WHERE (personID = ?)
bind => [552]
[EL Fine]: sql: 2012-07-13 17:25:52.327--ServerSession(1529073996)--Connection(328677993)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT registrationId, SEMESTERTYPE, version, YEAR, semesterCourseId, personID FROM REGISTRATION WHERE (personID = ?)
bind => [602]
[EL Fine]: sql: 2012-07-13 17:25:52.358--ServerSession(1529073996)--Connection(873312397)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT addressID, CITY, COUNTRY, STATE_US, STREETADDRESS, STREETADDRESS2, version, ZIPCODE FROM ADDRESS WHERE (addressID = ?)
bind => [2]
[EL Fine]: sql: 2012-07-13 17:25:52.365--ServerSession(1529073996)--Connection(509650638)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT applicantSchoolID, CREDITSCOMPLETED, FROMMONTH, FROMYEAR, GPA, NAME, SCHOOLTYPE, TOMONTH, TOYEAR, version, APPLICANT_personID FROM APPLICANTSCHOOL WHERE (APPLICANT_personID = ?)
bind => [151]
[EL Fine]: sql: 2012-07-13 17:25:52.385--ServerSession(1529073996)--Connection(17334753)--Thread(Thread["http-bio-8080"-exec-18,5,main])--SELECT applicantSchoolID, CREDITSCOMPLETED, FROMMONTH, FROMYEAR, GPA, NAME, SCHOOLTYPE, TOMONTH, TOYEAR, version, APPLICANT_personID FROM APPLICANTSCHOOL WHERE (APPLICANT_personID = ?)
bind => [51]
答案 0 :(得分:0)
您无法在JPA中嵌套联接,但在查询申请人时不需要 JPQL“从申请人中选择一个LEFT JOIN FETCH a.schools LEFT JOIN FETCH a.school,其中a.active =:active”应该有效,因为Appliant是一个人,所以学校关系也是如此。只有当申请人与人有关系并且您需要获取人和学校的加入时,才能进行嵌套。
如果是这种情况,EclipseLink允许批量读取或通过此处描述的查询提示进行连接: http://wiki.eclipse.org/EclipseLink/Examples/JPA/QueryOptimization
您还可以使用此处描述的EclipseLink注释在映射级别指定批处理/提取连接: http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_batchfetch.htm#CHDCCIDA 和 http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_joinfetch.htm#CEGFFHHA
批量读取将导致2个查询,而在1中获取连接。
对于上述查询,您还可以使用:
em.createQuery("Select a from Applicant a WHERE a.active = :active ")
.setParameter("active", true)
.setQueryHint("eclipselink.left-join-fetch", "a.schools");
.setQueryHint("eclipselink.left-join-fetch", "a.school");
.getResultList();