Критерий Query выбирает все связанные объекты, если не указано предложение where - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь выполнить простой критерий запроса.Однако выходные данные показывают, что вместо одного запроса выполняется 4 запроса, что является довольно неожиданным.

Мне интересно, я пропустил какие-либо ограничения в модели предметной области или запросе критериев.

Ниже приведеномодель предметной области.

enter image description here

Студент

    @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 Load.
  • Я имею в явном видеустановите @OneToOne как Lazy load.

    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 отношениями.Он загружен с нетерпением.

Если я добавлю ниже пункт, где.

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);

1 Ответ

0 голосов
/ 31 января 2019

, поскольку вы используете mappedby в объекте Student, это делает Passport владельцем отношения, и его необходимо загружать при загрузке Student.Один из вариантов - сделать ученика владельцем следующим образом:

Отображение студента

 @OneToOne( fetch = FetchType.LAZY)
 private Passport passport;

Отображение паспорта

@OneToOne(mappedBy="passport")
private Student student;

, добавив passport_id, будет добавлено к студентуТаблица.Если это невозможно, вы можете сделать однонаправленным отношение OneToOne (Студент -> Паспорт) или использовать параметр NO_PROXY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...