У меня есть две сущности: требование и продукт в приложении 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 =?
*