Spring Data @OneToMany (fetch = FetchType.EAGER) работает как режим запроса выбора. - PullRequest
0 голосов
/ 02 апреля 2020

Я прикрепил ниже свои коды. загружать детей по одному, когда я получаю все родительские объекты. Как ее решить?

parent table

Child Table

Класс родительского объекта. Он имеет 3 атрибута: идентификатор, имя и дочерние элементы. дети приписывают нагрузку охотно потому что мне нужен родительский объект с его потомками.

    @Entity
    @Table(name = "parent")
    public class Parent {
        @Id
        private int id;

        private String name;

        @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", fetch = FetchType.EAGER, orphanRemoval = true)
        private List<Child> children;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public List<Child> getChildren() {
            return children;
        }

        public void setChildren(List<Child> children) {
            this.children = children;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

Дочерний класс. Он имеет 3 свойства, такие как идентификатор, имя и родитель. родительское свойство загружается как ленивый режим. потому что я никогда не хочу дочерний объект с его родительским объектом.

    @Entity
    @Table(name = "child")
    public class Child {
        @Id
        private int id;

        @Column(name = "name")
        private String name;

        @JsonIgnore
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "parent", referencedColumnName = "id")
        private Parent parent;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Parent getParent() {
            return parent;
        }

        public void setParent(Parent parent) {
            this.parent = parent;
        }
    }

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

    protected List getAll(){
            EntityManager entityManager = entityManagerFactory.createEntityManager();
            entityManager.getTransaction().begin();
            List<Parent> objects = entityManager.createQuery("Select o from Parent o", Parent.class).getResultList();
            entityManager.getTransaction().commit();
            entityManager.close();
            return objects;
        }

Я ожидаю только один запрос на соединение. но вызовы гибернации запрашивают один за другим. Это получает n + 1 запрос проблемы.

    Hibernate: select parent0_.id as id1_8_, parent0_.name as name2_8_ from parent parent0_
    Hibernate: select children0_.parent as parent3_0_0_, children0_.id as id1_0_0_, children0_.id as id1_0_1_, children0_.name as name2_0_1_, children0_.parent as parent3_0_1_ from child children0_ where children0_.parent=?
    Hibernate: select children0_.parent as parent3_0_0_, children0_.id as id1_0_0_, children0_.id as id1_0_1_, children0_.name as name2_0_1_, children0_.parent as parent3_0_1_ from child children0_ where children0_.parent=?
    Hibernate: select children0_.parent as parent3_0_0_, children0_.id as id1_0_0_, children0_.id as id1_0_1_, children0_.name as name2_0_1_, children0_.parent as parent3_0_1_ from child children0_ where children0_.parent=?

1 Ответ

0 голосов
/ 02 апреля 2020

JPA не предоставляет каких-либо спецификаций для сопоставления аннотаций для выбора стратегии выборки.

Использование JOIN FETCH для извлечения как root сущностей, так и их сопоставленных сущностей / коллекций в одном запросе, который решил N + 1 запрос проблема. Как

SELECT distinct p FROM Parent p LEFT JOIN FETCH p.children
...