【问题标题】:How to properly create Nested Join using Criteria Builder如何使用 Criteria Builder 正确创建嵌套联接
【发布时间】:2012-05-07 21:55:23
【问题描述】:

我有三个实体 SchoolDepartmentProgram,每当我尝试加入其中两个实体时,都会引用第三个实体并所以我正在寻找一个使用标准构建器的示例,说明如何正确地从 Root 实体开始并正确加入。

我的学校实体是导致问题的原因。

public class School {

@NotNull
private String name;

@NotNull
private String code;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "schoolDepartment")
private Set<Department> departments = new HashSet<Department>();

@OneToMany(cascade = CascadeType.ALL, mappedBy = "school")
private Set<Program> programs = new HashSet<Program>();
}

程序实体

public class Program {

@NotNull
@Size(min = 0, max = 300)
private String name;

@NotNull
@Size(min = 0)
private String description;

private String code;

@Enumerated(EnumType.STRING)
private ProgramType programType;

@ManyToOne
private School school;

我尝试只加入上面的两个实体失败,EclipseLink 去引用第三个?

    // FROM program JOIN School 
Root<Program> program = cq.from(Program.class);

Join<School,Program> school =  program.join("school" , JoinType.INNER);
            //Join<School, Department> departmentJoin =    school.join("schoolDepartment", JoinType.LEFT);

             // SELECT task as Task, person as Person, ... 
             cq.multiselect(program,school);
             return program;  // EclipseLink requires a joined entity for the count

包含生成的 SQL 的完整堆栈跟踪。请注意它是如何开始引用 School 实体,然后在 Department 实体上调用 ReadAllObjectQuery 的?

[EL Fine]: sql: 2012-05-06 17:34:52.886--ServerSession(1839972036)--Connection(131165903)--Thread(Thread["http-bio-8080"-exec-3,5,main])--SELECT t0.id, t0.CODE, t0.NAME, t0.version, t1.programID, t1.ACTIVE, t1.CODE, t1.DESCRIPTION, t1.NAME, t1.PROGRAMTYPE, t1.REQUIREDCREDITS, t1.version, t1.SCHOOL_id FROM SCHOOL t0 LEFT OUTER JOIN PROGRAM t1 ON (t1.SCHOOL_id = t0.id), SCHOOL t2 WHERE (t2.id = t1.SCHOOL_id)
[EL Finest]: connection: 2012-05-06 17:34:52.888--ServerSession(1839972036)--Connection(354961667)--Thread(Thread["http-bio-8080"-exec-3,5,main])--Connection released to connection pool [read].
2012-05-06 17:34:52,896 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.School': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.School.entityManager
2012-05-06 17:34:52,896 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
2012-05-06 17:34:52,899 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.School': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.School.entityManager
2012-05-06 17:34:52,900 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
2012-05-06 17:34:52,901 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.School': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.School.entityManager
2012-05-06 17:34:52,901 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
2012-05-06 17:34:52,902 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.Program': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.Program.entityManager
2012-05-06 17:34:52,903 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
[EL Finest]: query: 2012-05-06 17:34:52.904--ServerSession(1839972036)--Thread(Thread["http-bio-8080"-exec-3,5,main])--Execute query ReadObjectQuery(name="school" referenceClass=School )
2012-05-06 17:34:52,908 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.Program': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.Program.entityManager
2012-05-06 17:34:52,908 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
[EL Finest]: transaction: 2012-05-06 17:34:52.908--UnitOfWork(2138845270)--Thread(Thread["http-bio-8080"-exec-3,5,main])--[EL Finest]: query: 2012-05-06 17:34:52.91--ServerSession(1839972036)--Thread(Thread["http-bio-8080"-exec-3,5,main])--Execute query ReadAllQuery(name="departments" referenceClass=Department )
[EL Finest]: connection: 2012-05-06 17:34:52.911--ServerSession(1839972036)--Connection(32490450)--Thread(Thread["http-bio-8080"-exec-3,5,main])--Connection acquired from connection pool [read].
[EL Finest]: connection: 2012-05-06 17:34:52.911--ServerSession(1839972036)--Thread(Thread["http-bio-8080"-exec-3,5,main])--reconnecting to external connection pool
[EL Fine]: sql: 2012-05-06 17:34:52.912--ServerSession(1839972036)--Connection(606146812)--Thread(Thread["http-bio-8080"-exec-3,5,main])--SELECT id, ACTIVE, CODE, DESCRIPTION, NAME, version, SCHOOLDEPARTMENT_id FROM DEPARTMENT WHERE (SCHOOLDEPARTMENT_id = ?)
    bind => [1]
[EL Finest]: connection: 2012-05-06 17:34:52.913--ServerSession(1839972036)--Connection(32490450)--Thread(Thread["http-bio-8080"-exec-3,5,main])--Connection released to connection pool [read].
2012-05-06 17:34:52,914 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.Department': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.Department.entityManager
2012-05-06 17:34:52,914 ["http-bio-8080"-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
[EL Finest]: query: 2012-05-06 17:34:52.915--ServerSession(1839972036)--Thread(Thread["http-bio-8080"-exec-3,5,main])--Execute query ReadObjectQuery(name="schoolDepartment" referenceClass=School )
[EL Finest]: query: 2012-05-06 17:34:52.915--ServerSession(1839972036)--Thread(Thread["http-bio-8080"-exec-3,5,main])--Execute query ReadAllQuery(name="programs" referenceClass=Program )
[EL Finest]: connection: 2012-05-06 17:34:52.916--ServerSession(1839972036)--Connection(63558014)--Thread(Thread["http-bio-8080"-exec-3,5,main])--Connection acquired from connection pool [read].
[EL Finest]: connection: 2012-05-06 17:34:52.916--ServerSession(1839972036)--Thread(Thread["http-bio-8080"-exec-3,5,main])--reconnecting to external connection pool
[EL Fine]: sql: 2012-05-06 17:34:52.917--ServerSession(1839972036)--Connection(920168739)--Thread(Thread["http-bio-8080"-exec-3,5,main])--SELECT programID, ACTIVE, CODE, DESCRIPTION, NAME, PROGRAMTYPE, REQUIREDCREDITS, version, SCHOOL_id FROM PROGRAM WHERE (SCHOOL_id = ?)

【问题讨论】:

  • 包括查询的完整代码和生成的 SQL
  • 我已经添加了生成 SQL 的堆栈跟踪。该查询是一个 Criteria Query,它从 Root 开始加入 School 并假设只是停在那里,但由于 School 有“部门”作为 oneToMany 参考,它会继续进行

标签: jpa join nested eclipselink


【解决方案1】:

我在每个 OneToMany 关系中添加了fetch = FetchType.Eager,因为它是延迟加载所有引用实体。不知道这是否是性能问题,但我想我还是需要这些列

【讨论】:

    猜你喜欢
    • 2021-06-18
    • 2015-07-31
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    相关资源
    最近更新 更多