gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:44:17 25 4
gpt4 key购买 nike

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

@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 代理替换(因为它是惰性的)。如果我想访问 parent 的 ID,我执行以下调用:

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.

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

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.

所以把你的代码改成:

@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;
}
...
}

相关问题

引用资料

关于java - Hibernate 在访问关联实体的 id 时生成 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3736818/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com