Hibernate正在使用@ManyToOne和@Lazy提取对象进行额外的SQL语句 [英] Hibernate is making extra SQL statement with @ManyToOne and @Lazy fetching object

查看:206
本文介绍了Hibernate正在使用@ManyToOne和@Lazy提取对象进行额外的SQL语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望有人向我解释为什么Hibernate在我直接的情况下要额外增加一条SQL语句.基本上我有这个对象:

I would like someone to explain me why Hibernate is making one extra SQL statement in my straight forward case. Basically i have this object:

@Entity
class ConfigurationTechLog (
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Long?,

        val configurationId: Long,

        val type: String,

        val value: String?
) {
        @JsonIgnore
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "configurationId", insertable = false, updatable = false)
        val configuration: Configuration? = null
}

如您所见,那里没有什么特别的.当我执行此查询时:

So as you can see, nothing special there. And when i execute this query :

@Query(value = "SELECT c FROM ConfigurationTechLog c where c.id = 10")
fun findById10() : Set<ConfigurationTechLog>

在我的控制台中,我看到以下内容:

In my console i see this:

Hibernate: 
    /* SELECT
        c 
    FROM
        ConfigurationTechLog c 
    where
        c.id = 10 */ select
            configurat0_.id as id1_2_,
            configurat0_.configuration_id as configur2_2_,
            configurat0_.type as type3_2_,
            configurat0_.value as value4_2_ 
        from
            configuration_tech_log configurat0_ 
        where
            configurat0_.id=10
Hibernate: 
    select
        configurat0_.id as id1_0_0_,
        configurat0_.branch_code as branch_c2_0_0_,
        configurat0_.country as country3_0_0_,
        configurat0_.merchant_name as merchant4_0_0_,
        configurat0_.merchant_number as merchant5_0_0_,
        configurat0_.org as org6_0_0_,
        configurat0_.outlet_id as outlet_i7_0_0_,
        configurat0_.platform_merchant_account_name as platform8_0_0_,
        configurat0_.store_type as store_ty9_0_0_,
        configurat0_.terminal_count as termina10_0_0_ 
    from
        configuration configurat0_ 
    where
        configurat0_.id=?

有人可以解释一下,这是怎么回事?第二个查询来自何处?

Can someone please explain me, what is happening here ? From where this second query is coming from ?

推荐答案

此链接可用于了解让我给你举个例子:

我有三门课程,每门课程都有与学生相关的课程. 我想执行"SELECT * FROM Courses".这是我想要的第一个查询(+1),但是在后台休眠,为了获取有关选择*给我们的每门课程的学生的详细信息,将执行另外三个查询,每门课程一个查询(N,有三个课程来自选择*).最后,我将看到4个对Hibernate Logs的查询

I have three Courses and each of them have Students related. I would like to perform a "SELECT * FROM Courses". This is the first query that i want (+ 1) but Hibernate in background, in order to get details about Students for each Course that select * given to us, will execute three more queries, one for each course (N, there are three Course coming from select *). In the end i will see 4 queries into Hibernate Logs

考虑之前的示例,可能是您遇到的情况:您执行所需的第一个查询,获取配置ID = 10,但是Hibernate之后将获取与此配置相关的实体,然后进行新查询执行以获取此相关实体.

Considering the example before, probably this is what happen in your case: You execute the first query that you want, getting Configuration Id = 10 but after, Hibernate, will take the entity related to this Configuration, then a new query is executed to get this related entity.

此问题应该与关系(当然)和LAZY Fetch有关.这不是您造成的问题,而是LAZY Fetch的休眠性能问题,请考虑将其视为错误或默认行为

This problem should be related in specific to Relationships (of course) and LAZY Fetch. This is not a problem that you have caused but is an Hibernate Performance Issue with LAZY Fetch, consider it a sort of bug or a default behaviour

要解决此类问题,我不知道您是否会遇到这种情况,但是...我知道三种方式:

To solve this kind of problem, i don't know if will be in your case but ... i know three ways:

  • EAGER提取类型(但不是最好的选择)
  • 使用课程和学生之间的JOIN FETCH查询
  • 创建用于表示课程的EntityGraph对象和用于表示学生的子图,并将其添加到EntityGraph

这篇关于Hibernate正在使用@ManyToOne和@Lazy提取对象进行额外的SQL语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆