Hibernate 在访问关联实体的 id 时生成 SQL 查询

编程入门 行业动态 更新时间:2024-10-11 09:21:00
本文介绍了Hibernate 在访问关联实体的 id 时生成 SQL 查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有看起来像这样的 Hibernate 实体(忽略了 getter 和 setter):

I have Hibernate Entities that look something like this (getters and setters left out):

@Entity
public class EntityA {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private EntityB parent;
}

@Entity
public class EntityB extends SuperEntity {
    @OneToMany(mappedBy = "parent")
    @Fetch(FetchMode.SUBSELECT)
    @JoinColumn(name = "parent_id")
    private Set<EntityA> children;
}

@MappedSuperclass
public class SuperEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private long itemId;
}

当我查询 EntityA 时,它加载良好,父关联被 Hibernate 代理替换(因为它是惰性的).如果我想访问父母的 id,我会执行以下调用:

When I query for EntityA it loads fine, with the parent association being replaced by a Hibernate proxy (as it is Lazy). If I want access to the parent's id I perform the following call:

EntityA entityA = queryForEntityA();
long parentId = entityA.getParent().getItemId();

据我所知,调用不应往返数据库,因为 Id 存储在 EntityA 表中,代理应仅返回该值.但是,在我的情况下,这会生成一个 SQL 语句,该语句获取 EntityB,然后才返回 Id.

As I understand that call should NOT make a roundtrip to the database, as the Id is stored in the EntityA table, and the proxy should only return that value. However, in my case this generates a SQL statement which fetches EntityB and only then returns the Id.

我该如何调查问题?这种不正确行为的一些可能原因是什么?

How can I investigate the problem? What are some likely causes of this incorrect behaviour?

推荐答案

据我所知,调用不应往返数据库,因为 Id 存储在 EntityA 表中,代理应仅返回该值.

As I understand that call should NOT make a roundtrip to the database, as the Id is stored in the EntityA table, and the proxy should only return that value.

使用属性访问类型.您遇到的行为是字段访问类型的限制".以下是 Emmanuel Bernard 的解释:

Use property access type. The behavior you're experiencing is a "limitation" of field access type. Here is how Emmanuel Bernard explained it:

这是不幸的,但在意料之中.这是字段级访问的限制之一.基本上我们无法知道 getId() 确实只是去访问 id 字段.所以我们需要加载整个对象以确保安全.

That is unfortunate but expected. That's one of the limitations of field level access. Basically we have no way to know that getId() indeed only go and access the id field. So we need to load the entire object to be safe.

因此将您的代码更改为:

So change your code into:

@Entity
public class EntityA {
    private EntityB parent;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    public EntityB getParent() {
        return parent; 
    }
    ...
}

@MappedSuperclass
public class SuperEntity {
    private long itemId;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    public long getItemId() { 
        return itemId;
    }
    ...
}

相关问题

休眠注释 - 哪个更好,字段或属性访问权限?

使用注释时在 getId 调用上加载代理在字段上proxy getId => 为什么会生成sql!HHH-3718(如果这个问题可以解决的话) Proxy loaded on getId-call when using annotations on fields proxy getId => why sql is generated ! HHH-3718 (if this issue can ever be solved)

这篇关于Hibernate 在访问关联实体的 id 时生成 SQL 查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

更多推荐

[db:关键词]

本文发布于:2023-03-28 15:12:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/733285.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实体   Hibernate   SQL   id

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!