Spring Boot: HIbernate продолжает вызывать сложные запросы внешнего соединения - PullRequest
0 голосов
/ 16 февраля 2019

У меня есть две сущности: требование и продукт в приложении Spring Boot.Требование имеет отношение «один ко многим» с продуктом.

В интерфейсе репо продукта у меня есть простой метод запроса, который выбирает список продуктов с заданным идентификатором require_id.Вот код:

interface ProductRepo: JpaRepository<Product, Int>{

 fun findProductsByRequirement_Id(id:Int) : List<Product>
}

Однако, когда этот метод вызывается из контроллера остатка, я вижу, что наряду с каждым продуктом hibernate возвращает соответствующий объект требования, а не просто require_id.На этом он не останавливается, он также возвращает все посторонние объекты (сделки и продажи), связанные с объектом требования в результате JSON.

Я установил эту опцию "spring.jpa.properties.hibernate.show_sql =true »в файле application.properties, и каждый раз, когда вызывается этот метод запроса, я вижу в консоли, что Hibernate продолжает вызывать множество сложных запросов на внешнее объединение, даже если я его не просил.На мой взгляд, это потребляет ненужный ресурс, когда мне не нужны все эти посторонние объекты.

Вот SQL-запросы, которые Hibernate запускает в фоновом режиме:

Hibernate: выберитеrequiremen0_.id, как id1_8_0_, requiremen0_.deal_id, как deal_id4_8_0_, requiremen0_.requirement_total как requirem2_8_0_, requiremen0_.sale_id, как sale_id5_8_0_, requiremen0_.title, как title3_8_0_, deal1_.id, как id1_4_1_, deal1_.account_id, как account_7_4_1_, deal1_.crm_customer_id, как crm_cust8_4_1_, deal1_.exp_closing_date, как exp_clos2_4_1_, deal1_.requirement_title как requirem3_4_1_, deal1_.sales_value как sales_va4_4_1_, deal1_.stage как stage5_4_1_, deal1_.type как type6_4_1_, deal1_.user_id, как user_id9_4_1_, account2_.id, как id1_0_2_, account2_.address, как address2_0_2_, account2_.crm_customer_id, какcrm_cust9_0_2_, account2_.email как email3_0_2_, account2_.key_person как key_pers4_0_2_, account2_.name как name5_0_2_, account2_.phone как phone6_0_2_, account2_.status как status7_0_2_, account2_.type, как type8_0_2_, account2_.user_id, как user_id10_0_2_, crmcustome3_.id, как id1_2_3_, crmcustome3_.address, как address2_2_3_, crmcustome3_.email как email3_2_3_, crmcustome3_.key_person как key_pers4_2_3_, crmcustome3_.name как name5_2_3_, crmcustome3_.number_of_users как number_o6_2_3_, crmcustome3_.телефон, как phone7_2_3_, crmcustome3_.subscription_type как subscrip8_2_3_, crmcustome3_.validity_exp_date как validity9_2_3_, user4_.id как id1_11_4_, user4_.crm_customer_id как crm_cust8_11_4_, user4_.designation как designat2_11_4_, user4_.hierarchy_level как hierarch3_11_4_, user4_.logged_in как logged_i4_11_4_, user4_.login_id какlogin_id5_11_4_, user4_.login_pw, как login_pw6_11_4_, user4_.name, как name7_11_4_, sale5_.id, как id1_9_5_, sale5_.crm_customer_id, как crm_cust4_9_5_, sale5_.deal_id, как deal_id5_9_5_, sale5_.sales_date, как sales_da2_9_5_, sale5_.sales_value, как sales_va3_9_5_, sale5_.user_id, как user_id6_9_5_,crmcustome6_.id как id1_2_6_, crmcustome6_.адрес как address2_2_6_, crmcustome6_.eпочта, как email3_2_6_, crmcustome6_.key_person как key_pers4_2_6_, crmcustome6_.name как name5_2_6_, crmcustome6_.number_of_users как number_o6_2_6_, crmcustome6_.phone как phone7_2_6_, crmcustome6_.subscription_type как subscrip8_2_6_, crmcustome6_.validity_exp_date как validity9_2_6_, deal7_.id в id1_4_7_, deal7_.account_id, какaccount_7_4_7_, deal7_.crm_customer_id, как crm_cust8_4_7_, deal7_.exp_closing_date как exp_clos2_4_7_, deal7_.requirement_title как requirem3_4_7_, deal7_.sales_value как sales_va4_4_7_, deal7_.stage как stage5_4_7_, deal7_.type, как type6_4_7_, deal7_.user_id, как user_id9_4_7_, user8_.id, как id1_11_8_,user8_.crm_customer_id в crm_cust8_11_8_, user8_.designation как designat2_11_8_, user8_.hierarchy_level как hierarch3_11_8_, user8_.logged_in как logged_i4_11_8_, user8_.login_id как login_id5_11_8_, user8_.login_pw как login_pw6_11_8_, user8_.name как name7_11_8_ от требований requiremen0_ левого внешнего объединения сделокdeal1_ on requiremen0_.deal_id = deal1_.id оставил внешнее объединение учетных записей account2_ на deal1_.account_id = account2_.id оставил внешнее объединение crm_customers crmcustome3_ на deal1_.crm_customer_id = crmcustome3_.id оставил внешнее присоединение пользователей user4_ на dealid_id_id_id_id_id_id0_idприсоединиться к продажам sale5_ on requiremen0_.sale_id = sale5_.id оставил внешнее объединение crm_customers crmcustome6_ на sale5_.crm_customer_id = crmcustome6_.id оставил внешнее объединенное предложение deal7_ on sale5_.deal_id = deal7_.id оставил внешнее присоединение user8__пользователя_доставки user__ на sales5_userгде requiremen0_.id =?

Что я могу сделать, чтобы избежать этой ситуации?

Вот классы сущностей для Продукта и Требования:

package com.ksk.crmserver.Model

import com.fasterxml.jackson.annotation.JsonIgnore
import javax.persistence.*

@Entity
@Table(name = "requirements")
data class Requirement(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Int = 0,
        @Column(name = "title")
        val title: String = "",

        @OneToMany(mappedBy = "requirement")
        @JsonIgnore
        val products: List<Product>? = null,
        @Column(name = "requirement_total")

        val requirementTotal: Int = 0,

        @ManyToOne
        var deal: Deal? = null,

        @ManyToOne
        val sale: Sale?=null
)


package com.ksk.crmserver.Model

import javax.persistence.*


@Entity
@Table(name = "products", indexes = [Index(name = "idx_product", columnList = "name")])

data class Product(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Int = 0,
        val name: String = "",
        val description: String? = "",

        @Column(name = "unit_cost")
        val unitCost: Double = 0.0,

        @Column(name = "qty")
        val qty: Double? = 0.0,

        val unit: String? = "",

        @Column(name = "total_Cost")
        val totalCost: Double? = 0.0,

        @Column(name = "profit_margin")
        val profitMargin: Double? = 0.0,

        val profit: Double? = 0.0,

        @Column(name = "vat_percentage")
        val vatPercentage: Double? = 0.0,

        val vat: Double? = 0.0,

        @Column(name = "total_price")
        val totalPrice: Double? = 0.0,

        @ManyToOne
        @JoinColumn(name = "requirement_id")
        val requirement: Requirement? = null


)

РедактироватьЯ пытался использовать EntityManager.getReference, чтобы получить экземпляр объекта Requirement.Но он все еще выполняет длинный SQL-запрос для получения требования по идентификатору из БД.Вот мой код из класса RestController для Product:

Боюсь, он все еще выполняет запрос sql join.Вот мой код контроллера отдыха:

@RestController
@CrossOrigin
class ProductRoute(val productRepo: ProductRepo, val requirementRepo: RequirementRepo) {

    @Autowired
    val entityManager: EntityManager?=null

    @GetMapping("/get/productsByReqId")
    fun getProductsByRequirementId(@RequestParam id: Int): List<Product> {
        val requirement = this.entityManager?.getReference(Requirement::class.java, id) as Requirement
        print("Done fetching the requirement")
        return this.productRepo.findProductsByRequirement(requirement)
    }

Это sql Hibernate работает:

Hibernate: выберите requiremen0_.id в качестве id1_8_0_, requiremen0_.deal_id в качестве deal_id4_8_0_, requiremen0_.requirement_total, как requirem2_8_0_, requiremen0_.sale_id, как sale_id5_8_0_, requiremen0_.title как title3_8_0_, deal1_.id, как id1_4_1_, deal1_.account_id, как account_7_4_1_, deal1_.crm_customer_id, как crm_cust8_4_1_, deal1_.exp_closing_date как exp_clos2_4_1_, deal1_.requirement_title как requirem3_4_1_, как deal1_.sales_valuesales_va4_4_1_, deal1_.stage, как stage5_4_1_, deal1_.type как type6_4_1_, deal1_.user_id, как user_id9_4_1_, account2_.id, как id1_0_2_, account2_.address, как address2_0_2_, account2_.crm_customer_id, как crm_cust9_0_2_, account2_.email, как email3_0_2_, account2_.key_person, как key_pers4_0_2_,account2_.name как name5_0_2_, account2_.phone как phone6_0_2_, account2_.status как status7_0_2_, account2_.type как type8_0_2_, account2_.user_id как user_id10_0_2_, crmcustome3_.id как id1_2_3_, crmcustome3_.address, как address2_2_3_, crmcustome3_.email как email3_2_3_, crmcustome3_.key_person как key_pers4_2_3_, crmcustome3_.name как name5_2_3_, crmcustome3_.number_of_users как number_o6_2_3_, crmcustome3_.phone как phone7_2_3_, crmcustome3_.subscription_type как subscrip8_2_3_, crmcustome3_.validity_exp_date как validity9_2_3_,user4_.id, как id1_11_4_, user4_.crm_customer_id, как crm_cust8_11_4_, user4_.designation как designat2_11_4_, user4_.hierarchy_level как hierarch3_11_4_, user4_.logged_in как logged_i4_11_4_, user4_.login_id как login_id5_11_4_, user4_.login_pw как login_pw6_11_4_, user4_.name как name7_11_4_, products5_.ID_идентификатора как require13_5_5_, products5_.id как id1_5_5_, products5_.id как id1_5_6_, products5_.description как descript2_5_6_, products5_.name как name3_5_6_, products5_.profit как прибыль4_5_6_, products________5_5_5_5_5_5_5_5__5_5_5_5__5_5__5_5_5 как_5__5require13_5_6_, products5_.total_cost as total_co7_5_6_, products5_.total_price, как total_pr8_5_6_, products5_.unit как unit9_5_6_, products5_.unit_cost как unit_co10_5_6_, products5_.vat как vat11_5_6_, products5_.vat_percentage как vat_per12_5_6_, sale6_.id, как id1_9_7_, sale6_.crm_customer_id, как crm_cust4_9_7_, sale6_.deal_id, как deal_id5_9_7_, sale6_.sales_date, как sales_da2_9_7_, sale6_.sales_value как sales_va3_9_7_, sale6_.user_id, как user_id6_9_7_, crmcustome7_.id, как id1_2_8_, crmcustome7_.address, как address2_2_8_, crmcustome7_.email как email3_2_8_, crmcustome7_.key_person как key_pers4_2_8_, crmcustome7_.name как name5_2_8_, как crmcustome7_.number_of_usersnumber_o6_2_8_, crmcustome7_.phone, как phone7_2_8_, crmcustome7_.subscription_type как subscrip8_2_8_, crmcustome7_.validity_exp_date, как validity9_2_8_, deal8_.id, как id1_4_9_, deal8_.account_id, как account_7_4_9_, deal8_.crm_customer_id, как crm_cust8_4_9_, deal8_.exp_closing_date, как exp_clos2_4_9_,deal8_.requirement_title, как requirem3_4_9_, deal8_.sales_value как sales_va4_4_9_, deal8_.stage как stage5_4_9_, deal8_.type как type6_4_9_, deal8_.user_id, как user_id9_4_9_, user9_.id, как id1_11_10_, user9_.crm_customer_id, как crm_cust8_11_10_, user9_.designation как designat2_11_10_, user9_.hierarchy_level в hierarch3_11_10_, user9_.logged_in в logged_i4_11_10_, user9_.login_id как login_id5_11_10_, user9_.login_pw как login_pw6_11_10_, user9_.name как name7_11_10_ от требований requiremen0_ левого внешнего объединения сделок deal1_ на requiremen0_.deal_id = deal1_.id левое внешнее объединение счетов account2_ на deal1_.account_id = account2_.id оставил внешнее объединение crm_customers crmcustome3_ на deal1_.crm_customer_id = crmcustome3_.id оставил внешнее объединение пользователей user4_ на deal1_.user_id = user4_.id оставил внешнее объединение products5_ on requiremen0_.id = продажа продажon requiremen0_.sale_id = sale6_.id оставил внешнее соединение crm_customers crmcustome7_ на sale6_.crm_customer_id = crmcustome7_.id left предложения о внешнем объединении deal8_ on sale6_.deal_id = deal8_.id оставленные пользователи внешнего присоединения user9_ on sale6_.user_id = user9_.id где requiremen0_.id =?

Завершено получение требования 2019-02-16 21: 01: 00.341 INFO 80558 --- [nio-8080-exec-1] ohhiQueryTranslatorFactoryInitiator: HHH000397: Использование ASTQueryTranslatorFactory

Hibernate: выбрать продукт0_.id как id1_5_, product0_.description как descript2_5_, product0_.name как name3_5_, product0_.profit как profit4_5_, product0_.profit_margin как profit_m5_5_, product0_.qty как qty6_5_, product0_.requirement_id___________________как total_pr8_5_, product0_.unit как unit9_5_, product0_.unit_cost как unit_co10_5_, product0_.vat как vat11_5_, product0_.vat_percentage как vat_per12_5_ из продуктов product0_, где product0_.requirement_id =?

*

1 Ответ

0 голосов
/ 16 февраля 2019

Вы можете установить fetchType ваших отношений ManyToOne в Lazy (по умолчанию для отношений ManyToOne установлено значение Eager).Таким образом, Hibernate будет загружать ссылочные объекты только при их вызове.Если вы хотите, чтобы Hibernate возвращал идентификатор вместо всего объекта, на который есть ссылка, вы можете посмотреть здесь: Hibernate - внешние ключи вместо сущностей

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