Jpa fetch и n + 1 выпуск - PullRequest
       23

Jpa fetch и n + 1 выпуск

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

Я использую весеннюю загрузку 2, jpa и hibernate.

Моя сущность

@Entity
public class Samples {

    @EmbeddedId
    private SampleId id;

    @MapsId("samplingId")
    @ManyToOne(optional = false)
    private Samplings sampling;

    @OneToOne(mappedBy = "sample", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    private TestSamples testSamples;
    ...
}

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Samplings {
    @OneToOne
    private Products product;

    @OneToOne
    private Machines machine;

    @OneToOne(fetch = FetchType.LAZY)
    private Dimensions dimension;

    @OneToOne(fetch = FetchType.LAZY)
    private Colors color;

    @OneToMany(mappedBy = "sampling", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Samples> samples = new ArrayList<>();
    ...
}

@Entity
public class TestSamples {

    @Id
    @SequenceGenerator(name = "test_samples_id_seq", sequenceName = "test_samples_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "test_samples_id_seq")
    private Integer id;

    @OneToOne(fetch = FetchType.LAZY)
    private Samples sample;
    ... 

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private Absorptions absorptionTest;

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private Compressions compressionTest;

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private BnqDurabilities bnqDurabilityTest;

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private CsaDurabilities csaDurabilityTest;

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private BnqScallings bnqScallingTest;

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private CsaScallings csaScallingTest;

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private Flexions flexionTest;

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private Granulometries granulometryTest;

    @OneToOne(mappedBy = "testSample", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private ExternalLabs externalLabTest;

}

@Entity
public class Absorptions extends BaseEntity {
    @OneToOne(fetch = FetchType.LAZY)
    private TestSamples testSample;
    ...
}

У меня огромный запрос со многими объединениями

        "select s from Samples s "
        + "Join Fetch s.testSamples ts "
        + "Join Fetch s.sampling sp "
        + "Left Join fetch sp.machine m "
        + "Join Fetch m.factory f "
        + "Join Fetch sp.product p "
        + "Join Fetch p.productType pt "
        + "Left Join fetch sp.color c "
        + "Left Join fetch sp.dimension d "
        + "Left Join fetch ts.compressionTest ct "
        + "Left Join Fetch ts.flexionTest as ft "
        + "Left Join Fetch ts.csaDurabilityTest as csaDt "
        + "Left Join Fetch ts.bnqDurabilityTest as bqnDt "
        + "Left Join Fetch ts.csaScallingTest as csaSt "
        + "Left Join Fetch ts.bnqScallingTest as bnqSt "
        + "Left Join fetch ts.absorptionTest at "
        + "where sp.externalLaboratoryResults=false "
        + "and sp.buildDate between :startDate and :endDate "
        + "and ts.granulometry=false "
        + "and ("
        + "ct.completed=true   "
        + "or ft.completed=true "
        + "or csaDt.completed=true "
        + "or bqnDt.completed=true "
        + "or csaSt.completed=true "
        + "or bnqSt.completed=true "
        + "or at.completed=true"
        + ") "
        + "order by s.id.samplingId,s.id.sampleLetter")

Hibernate перевести это на

https://paste.ee/p/vrP5V

Hibernate генерирует большой запрос, но многие для сжатия, теста, flexionTest .... не понимаю, почему я получил

Ответы [ 2 ]

1 голос
/ 02 апреля 2019

В Hibernate для отношений OneToOne без опционального = false всегда будет соединение, даже с FetchType.LAZY.

Это потому, что, например, поле TestSamples.flexionTest, Hibernate должен знать, должен ли он предоставить прокси-объект или нуль. Так что в любом случае он должен запросить таблицу flexionTest, даже для FetchType.LAZY.

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

Если я правильно понял, у вас много вопросов.

В переведенном SQL существует много запросов к external_labs и granulometries таблицам.

Чтобы избежать этих отдельных запросов, присоединитесь также к granulometryTest и externalLabTest

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