我读到了 getOne()
延迟加载和 findOne()
立即获取整个实体。我检查了调试日志,我什至在我的 sql 服务器上启用了监控以查看执行了哪些语句,我发现 getOne()
和 findOne()
生成并执行相同的查询。但是当我使用 getOne()
这些值最初为空(当然除了 id)。
那么谁能告诉我,如果这两种方法都在数据库上执行相同的查询,为什么我应该使用一种而不是另一种?我基本上是在寻找一种方法来获取一个实体,而无需获取其所有子项/属性。
编辑 1:
Entity code
道号:
@Repository
public interface FlightDao extends JpaRepository<Flight, Long> {
}
Debugging log findOne() vs getOne()
编辑2:
感谢 Chlebik,我能够确定问题所在。就像 Chlebik 所说的那样,如果您尝试访问由
getOne()
获取的实体的任何属性将执行完整查询。就我而言,我在调试时检查行为,一次移动一行,我完全忘记了在调试 IDE 时尝试访问对象属性以进行调试(或者至少我认为这是正在发生的),因此调试触发完整的查询执行。我停止调试,然后检查日志,一切似乎都正常。getOne()
对比 findOne()
(此日志取自 MySQL general_log
而不是 hibernate 状态。Debugging log
No debugging log
最佳答案
这只是一个猜测,但在“纯 JPA”中,有一个名为 的 EntityManager 方法。获取引用 .它旨在检索其中只有 ID 的实体。它的用途主要是指示存在引用,而无需检索整个实体。也许代码会告诉更多:
// em is EntityManager
Department dept = em.getReference(Department.class, 30); // Gets only entity with ID property, rest is null
Employee emp = new Employee();
emp.setId(53);
emp.setName("Peter");
emp.setDepartment(dept);
dept.getEmployees().add(emp);
em.persist(emp);
我假设然后 getOne 用于相同的目的。为什么生成的查询和你问的一样?好吧,JPA 圣经中的 AFAIR - Pro JPA2 by Mike Keith 和 Merrick Schincariol - 几乎每个段落都包含诸如“行为取决于供应商”之类的内容。
编辑:
我已经设置了自己的设置。最后我得出的结论是,如果您以任何方式干扰用 获取的实体getOne (甚至使用 entity.getId())它会导致执行 SQL。尽管如果您仅使用它来创建代理(例如,用于上面代码中所示的关系指示器),则不会发生任何事情并且不会执行其他 SQL。所以我假设在你的服务类中你对这个实体做了一些事情(使用 getter,记录一些东西),这就是为什么这两种方法的输出看起来相同。
ChlebikGitHub with example code
SO helpful question #1
SO helpful question #2
关于spring - CrudRepository findOne() 和 JpaRepository getOne() 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33218762/