hibernate - 使用 entityManager.getReference() 和休眠和 spring 数据 jpa 获取实体代理时避免不必要的 SQL 选择查询
问题描述
在尝试使用 Hibernate 作为持久性提供程序通过 Spring 数据存储库获取实体引用时,我正在努力处理不必要的 SQL 选择查询。我的案例涉及多次讨论有关使用entityManager.getReference()
的问题,以便在此处和此处id
获取仅具有初始化值的代理对象。但这并不像描述的那样工作。
我有以下环境和代码
- 带有 Hibernate 的 Spring Boot JPA 项目
- 一个死的简单实体
Foo
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "d20_foo")
public class Foo {
@Id
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在我的服务代码中,我getReference
只是像这样调用
@Service
@Transactional
public class MyService {
@PersistenceContext
private EntityManager entityManager;
...
public void getFooLink() {
...
Foo foo = entityManager.getReference(Foo.class,1L);
...
}
...
}
在调试模式下的休眠日志中,我看到,一旦我点击getReference
,就会执行以下选择查询
Hibernate:
select
foo0_.id as id1_0_0_,
foo0_.name as name2_0_0_
from
d20_foo foo0_
where
foo0_.id=?
这是为什么?为什么执行查询而不是只返回代理对象?
我没有点击任何其他字段(例如在返回的对象上调用 getName() )并且按照参考实现中的描述进行了所有操作。
我不需要额外的查询 -Foo
实体是一个只读对象,我需要它作为另一个实体的引用对象。
解决方案
最后我想答案很简单。
这是一种调试模式(尤其是在 IntelliJ IDEA中)欺骗了我并显示了这些日志。当我尝试在不调试的情况下监视此代码时(只是将日志写入控制台)-一切都很好。也许当我在调试我的 IDE 时调用一些属性访问器(可能是一个name
字段),这会导致 Hibernate 执行选择查询来初始化代理。
所以最后一切都按预期工作
推荐阅读
- r - 如何使用R找到单词的平均值
- git - 在提交消息 gitlab 中链接另一个提交的引用
- python - 如何在 Python 中将(有些复杂的)Postgresql 语句转换为 SQLAlchemy ORM?
- sql - 如何在 SQL Server 中将 varchar '15:01:2008 02:07:23 PM' 转换为 datetime
- kubernetes - Kubernetes 将 pod 修改复制到其他 pod
- java - Spring Long.parseLong() 给出 com.google.protobuf.GeneratedMessageV3 类型无法解析
- sequelize.js - 在 Nestjs/sequelize 上的 sequelize-typescript 中定义关系时出错
- java - Oracle Continuos 查询通知 ORA-29979
- view - RP 粒子与介词
- ios - 在 ServerTrustPolicy.swift 文件中使用未解析的标识符“SecTrustEvaluateWithError”