我正在尝试运行一个简单的条件查询。然而,输出节目4次的查询被执行,而不是一个单一的查询这是相当出乎意料的。
我想知道,我是否错过了域模型或条件查询中的任何约束。
下面是域模型。
学生
@Entity
public class Student {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@OneToOne(mappedBy="student", fetch = FetchType.LAZY)
private Passport passport;
...
}
护照
@Entity
public class Passport {
@Id
@GeneratedValue
private Long id;
@Column
private String number;
@OneToOne
private Student student;
}
我已使用以下条件查询来获取学生记录。 我还想提到有关关系映射的几点。
@ManyToMany
和@OneToMany
关系默认为Lazy
加载。我已将@OneToOne
明确设置为Lazy
负载。
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Student> cq = builder.createQuery(Student.class);
Root<Student> root = cq.from(Student.class);
cq.select(root);
//cq.where(builder.equal(root.get("id"), 10001L));
List<Student> resultList = em.createQuery(cq).getResultList();
resultList.forEach(s -> log.info("{}",s));
以下是输出:
2019-01-30 15:34:40.883 INFO 13760 --- [ main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
Hibernate:
select
student0_.id as id1_4_,
student0_.name as name2_4_
from
student student0_
2019-01-30 15:34:41.436 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_4_] : [BIGINT]) - [2001]
2019-01-30 15:34:41.444 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name2_4_] : [VARCHAR]) - [Irshad]
2019-01-30 15:34:41.445 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_4_] : [BIGINT]) - [2002]
2019-01-30 15:34:41.446 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name2_4_] : [VARCHAR]) - [Ahmad]
2019-01-30 15:34:41.446 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_4_] : [BIGINT]) - [2003]
2019-01-30 15:34:41.446 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name2_4_] : [VARCHAR]) - [Sheikh]
2019-01-30 15:34:41.460 TRACE 13760 --- [ main] org.hibernate.type.CollectionType : Created collection wrapper: [com.initgrep.jpademo.student.Student.addresses#2001]
2019-01-30 15:34:41.460 TRACE 13760 --- [ main] org.hibernate.type.CollectionType : Created collection wrapper: [com.initgrep.jpademo.student.Student.courses#2001]
Hibernate:
select
passport0_.id as id1_2_1_,
passport0_.number as number2_2_1_,
passport0_.student_id as student_3_2_1_,
student1_.id as id1_4_0_,
student1_.name as name2_4_0_
from
passport passport0_
left outer join
student student1_
on passport0_.student_id=student1_.id
where
passport0_.student_id=?
2019-01-30 15:34:41.465 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [2001]
2019-01-30 15:34:41.466 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_4_0_] : [BIGINT]) - [2001]
2019-01-30 15:34:41.466 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_2_1_] : [BIGINT]) - [4001]
2019-01-30 15:34:41.467 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([number2_2_1_] : [VARCHAR]) - [E1001]
2019-01-30 15:34:41.467 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([student_3_2_1_] : [BIGINT]) - [2001]
2019-01-30 15:34:41.475 TRACE 13760 --- [ main] org.hibernate.type.CollectionType : Created collection wrapper: [com.initgrep.jpademo.student.Student.addresses#2002]
2019-01-30 15:34:41.476 TRACE 13760 --- [ main] org.hibernate.type.CollectionType : Created collection wrapper: [com.initgrep.jpademo.student.Student.courses#2002]
Hibernate:
select
passport0_.id as id1_2_1_,
passport0_.number as number2_2_1_,
passport0_.student_id as student_3_2_1_,
student1_.id as id1_4_0_,
student1_.name as name2_4_0_
from
passport passport0_
left outer join
student student1_
on passport0_.student_id=student1_.id
where
passport0_.student_id=?
2019-01-30 15:34:41.476 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [2002]
2019-01-30 15:34:41.477 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_4_0_] : [BIGINT]) - [2002]
2019-01-30 15:34:41.477 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_2_1_] : [BIGINT]) - [4002]
2019-01-30 15:34:41.477 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([number2_2_1_] : [VARCHAR]) - [E1002]
2019-01-30 15:34:41.478 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([student_3_2_1_] : [BIGINT]) - [2002]
2019-01-30 15:34:41.478 TRACE 13760 --- [ main] org.hibernate.type.CollectionType : Created collection wrapper: [com.initgrep.jpademo.student.Student.addresses#2003]
2019-01-30 15:34:41.478 TRACE 13760 --- [ main] org.hibernate.type.CollectionType : Created collection wrapper: [com.initgrep.jpademo.student.Student.courses#2003]
Hibernate:
select
passport0_.id as id1_2_1_,
passport0_.number as number2_2_1_,
passport0_.student_id as student_3_2_1_,
student1_.id as id1_4_0_,
student1_.name as name2_4_0_
from
passport passport0_
left outer join
student student1_
on passport0_.student_id=student1_.id
where
passport0_.student_id=?
2019-01-30 15:34:41.479 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [2003]
2019-01-30 15:34:41.479 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_4_0_] : [BIGINT]) - [2003]
2019-01-30 15:34:41.479 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_2_1_] : [BIGINT]) - [4003]
2019-01-30 15:34:41.480 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([number2_2_1_] : [VARCHAR]) - [E1003]
2019-01-30 15:34:41.480 TRACE 13760 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([student_3_2_1_] : [BIGINT]) - [2003]
2019-01-30 15:34:41.480 DEBUG 13760 --- [ main] o.h.stat.internal.StatisticsImpl : HHH000117: HQL: select generatedAlias0 from Student as generatedAlias0, time: 61ms, rows: 3
2019-01-30 15:34:41.484 INFO 13760 --- [ main] i.StatisticalLoggingSessionEventListener : Session Metrics {
170294 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
**5107615 nanoseconds spent preparing 4 JDBC statements;
5699493 nanoseconds spent executing 4 JDBC statements;**
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
我假设,条件查询不遵守实体上声明的FetchType.LAZY
。由于Student -> Passport
是1-1
的关系。它很热切。
如果我添加以下where子句。
cq.where(builder.equal(root.get("id"), 10001L))
仅获取学生,而不会得到以下输出所证实的其他关系。
Hibernate:
select
student0_.id as id1_4_,
student0_.name as name2_4_
from
student student0_
where
student0_.id=10001
2019-01-30 15:43:12.662 DEBUG 5964 --- [ main] o.h.stat.internal.StatisticsImpl : HHH000117: HQL: select generatedAlias0 from Student as generatedAlias0 where generatedAlias0.id=10001L, time: 22ms, rows: 0
2019-01-30 15:43:12.665 INFO 5964 --- [ main] i.StatisticalLoggingSessionEventListener : Session Metrics {
169108 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
4718825 nanoseconds spent preparing 1 JDBC statements;
7554940 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
更新:插入脚本。
INSERT INTO STUDENT(id,name) VALUES (2001, 'Irshad');
INSERT INTO STUDENT(id,name) VALUES (2002, 'Ahmad');
INSERT INTO STUDENT(id,name) VALUES (2003, 'Sheikh');
INSERT INTO PASSPORT(id, number, student_id) VALUES (4001, 'E1001', 2001);
INSERT INTO PASSPORT(id, number, student_id) VALUES (4002, 'E1002', 2002);
INSERT INTO PASSPORT(id, number, student_id) VALUES (4003, 'E1003', 2003);
答案 0 :(得分:0)
由于您在Student实体中使用mappedby
,因此它使Passport成为关系的所有者,并且在加载Student时必须对其进行加载。
一种选择是像这样使学生成为所有者:
学生映射
@OneToOne( fetch = FetchType.LAZY)
private Passport passport;
护照映射
@OneToOne(mappedBy="passport")
private Student student;
通过执行此操作 passport_id
将被添加到学生表。如果您不能这样做,则可以将OneToOne关系设为单向(学生->护照),也可以使用NO_PROXY选项。