当前位置: 首页 > 知识库问答 >
问题:

Hibernate@OneToOne即使使用@Fetch(FetchMode.JOIN)也会执行多个查询

朱刚捷
2023-03-14

考虑和<代码>雇员< /代码>和<代码>地址< /代码>关系。在员工地址之间有一对一的映射。以下是模型:

@Entity
@Table(name = "Address")
public class Address
{
    @Id
    @GeneratedValue
    @Column(name = "addressId")
    private int addressId;

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

    .
    .
}

@Entity
@Table(name = "Employee")
public class Employee
{
    @Id
    @Column(name = "employeeId")
    private int employeeId;

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

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "addressId")
    @Fetch(FetchMode.JOIN)
    private Address address;

    .
    .
}

现在,当我执行以下HQL查询时,它会在内部生成两个查询。一个取员工,另一个取地址。

”来自员工,其中id=“1

由Hibernate生成的SQL查询

Hibernate:选择employee0\uu0。employeeId为employeeId0_0,employee0_0。addressId为addressId0_0,employee0_0。从employee0_uo中取名称为name0_o,其中employee0_o。employeeId=1

Hibernate:选择address0_. addressId作为addressId1_0_,address0_. city作为city1_0_从地址address0_address0_. addressId=?

因为我使用的是@Fetch(FetchMode.JOIN),所以我希望Hibernate只执行一个带有JOIN的查询,一次性获取员工和地址数据。

你知道为什么它要执行两个查询吗?我如何让Hibernate使用join只执行一个查询?

我正在使用Hibernate 3.3.0。

共有2个答案

罗渝
2023-03-14

@OneToOne(fetch=FetchType.eanger)@fetch(FetchMode.JOIN)与这里提到的一样,您正在急切地加载地址,这意味着无论何时员工被要求获取地址,都将按照此提示进行获取

仅当您访问关联时,才会执行第二次选择。

这意味着只有在访问地址时才会执行查询,因此您应该使用@Fetch(FetchMode.选择)@OneToOne(读取=FetchType。懒惰)

更新:

当使用@Swathi的postFetchMode时,Hibernate总是忽略@Swathi的引用Query,在这种情况下,它会对每个单独的实体、集合或联接加载使用html" target="_blank">select。这意味着你必须创造并加入你自己

对于延迟加载,Hibernate将忽略通过注释提供的FetchType,但如果映射是通过XML完成的,例如Employee。哈佛商学院。xml和类似的东西

 <one-to-one name="address" fetch="join" class="**PACKAGE**.Address"
        constrained="true" ></one-to-one>

然后Hibernate将尊重延迟加载,并且只执行第一个选择语句,如果一对一上设置了延迟="false",那么它将执行两个选择语句。

陆信瑞
2023-03-14

使用显式HQL查询“FROM Employee WHERE id=“1”,Hibernate将不遵守带注释的获取模式。您需要在HQL查询中指定联接,或在条件中指定获取模式。

冬眠3。在使用查询接口(Session.createQuery)时,x会忽略Fetch模式注释,因此在这种情况下,必须向查询的FROM部分添加一个内部JOIN Fetch子句。

 类似资料:
  • 我正在使用spring boot开发REST应用程序,并试图优化查询的性能。我目前正在使用存储库中的,这会导致性能问题。代码如下: 个人实体 密码实体 角色实体 人员存储库 当我做一个时,在人表中的每一行都会触发选择查询,以获取密码和角色。我知道我可以在存储库中使用注释和来强制生成单个查询,但是我想知道是否有其他方法可以这样做。我正在寻找我们可以在实体级别上做的事情来减少查询。 使用Spring

  • 我希望在一个select请求中运行以下查询: 问题是所有内容都是由单独的多个查询获取的。我只希望团队和团队的球员和每个球员的技能在一个请求中被获取。但是相反,我有多个选择查询来获取每个团队、玩家、每个玩家的统计数据和技能。 以下是与注释一起使用的实体: 游戏实体: 团队实体: 玩家实体: 你能指出所犯的错误吗?我需要一个选择查询来加载游戏,它是团队、团队的球员和每个球员的技能。 编辑1:以下是po

  • 和我的持久性类: 我不明白问题出在哪里?

  • 问题内容: 我正在运行一个简单的Calculator应用程序来学习Java的异常处理。我设置了两个要处理的异常:InputMismatchException和ArithmeticException,用于除以零。 ArithmeticException得到处理,并且do-while循环继续。但是在捕获InputMismatchException之后,执行将终止而不是继续循环。 码: 输出: 预期:在

  • 我有以下问题。 每当使用JOIN FETCH子句使用查询调用我的存储库时,Hibernate都会生成一个根本不需要的附加查询。这里的主要问题是,根据相应的数据库结构,两个实体(对应于两个单独的表)应该由与两个实体的ID不同的列连接(即@JoinCol列在实体顺序中表示的“Custerid”(name=“Custerid”,引用的列名称=“Custerid”)”)。 存储库如下所示: 每当我调用ge

  • 问题内容: 我不确定为什么它不显示sql语句。我之前使用过它(在较早的春天,这次我使用3) 在ApplicationContext中,我有: 在log4j中: 其他一切似乎都很好,但是它并没有显示sql。 我有想念吗? (或者是否可以从org.hibernate.cfg.Environment.getProperties()的SessionFactory打印?它没有显示show_sql,可能甚至没