CrudRepository findOne() 和 JpaRepository getOne() 的区别 [英] Difference between CrudRepository findOne() and JpaRepository getOne()

查看:31
本文介绍了CrudRepository findOne() 和 JpaRepository getOne() 的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到 getOne() 是延迟加载的,findOne() 会立即获取整个实体.我检查了调试日志,我什至在我的 sql 服务器上启用了监控以查看执行了哪些语句,我发现 getOne()findOne() 生成和执行相同的查询.但是,当我使用 getOne() 时,这些值最初为空(当然 id 除外).

I read that getOne() is lazy loaded and findOne() fetches the whole entity right away. I've checked the debugging log and I even enabled monitoring on my sql server to see what statements gets executed, I found that both getOne() and findOne() generates and executes the same query. However when I use getOne() the values are initially null (except for the id of course).

那么谁能告诉我,如果这两种方法都对数据库执行相同的查询,为什么我应该使用一种方法而不是另一种方法?我基本上是在寻找一种方法来获取一个实体,而无需获取其所有子项/属性.

So could anyone please tell me, if both methods executes the same query on the database, why should I use one over the other? I'm basically looking for a way to fetch an entity without getting all of its children/attributes.

实体代码

道码:

@Repository
public interface FlightDao extends JpaRepository<Flight, Long> {
}

调试日志 findOne() 与 getOne()

多亏了 Chlebik,我才能够确定问题所在.就像 Chlebik 所说的那样,如果您尝试访问由 getOne() 获取的实体的任何属性,则将执行完整查询.就我而言,我在调试时检查行为,一次移动一行,我完全忘记了在调试 IDE 时尝试访问对象属性以进行调试(或者至少我认为正在发生这种情况),因此调试触发完整的查询执行.我停止调试,然后查看日志,一切正常.

Thanks to Chlebik I was able to identify the problem. Like Chlebik stated, if you try to access any property of the entity fetched by getOne() the full query will be executed. In my case, I was checking the behavior while debugging, moving one line at a time, I totally forgot that while debugging the IDE tries to access object properties for debugging purposes (or at least that's what I think is happening), so debugging triggers the full query execution. I stopped debugging and then checked the logs and everything appears to be normal.

getOne() vs findOne()(此日志取自 MySQL general_log 而非休眠.

getOne() vs findOne() (This log is taken from MySQL general_log and not hibernate.

调试日志

无调试日志

推荐答案

这只是一个猜测,但在纯 JPA"中有一个名为 getReference 的 EntityManager 方法.它旨在检索其中只有 ID 的实体.它的用途主要是用于指示存在引用而无需检索整个实体.也许代码会告诉更多:

It is just a guess but in 'pure JPA' there is a method of EntityManager called getReference. And it is designed to retrieve entity with only ID in it. Its use was mostly for indicating reference existed without the need to retrieve whole entity. Maybe the code will tell more:

// 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 - 几乎每个段落都包含诸如行为取决于供应商"之类的内容.

I assume then getOne serves the same purpose. Why the queries generated are the same you ask? Well, AFAIR in JPA bible - Pro JPA2 by Mike Keith and Merrick Schincariol - almost every paragraph contains something like 'the behaviour depends on the vendor'.

我已经设置了自己的设置.最后我得出的结论是,如果您以任何方式干扰使用 getOne 获取的实体(甚至使用 entity.getId()),它会导致执行 SQL.尽管如果您仅使用它来创建代理(例如,用于上面代码中所示的关系指示器),则不会发生任何事情并且不会执行其他 SQL.所以我假设在你的服务类中你对这个实体做了一些事情(使用 getter,记录一些东西),这就是为什么这两个方法的输出看起来一样.

I've set my own setup. Finally I came to conclusion that if You in any way interfere with entity fetched with getOne (even go for entity.getId()) it causes SQL to be executed. Although if You are using it only to create proxy (eg. for relationship indicator like shown in a code above), nothing happens and there is no additional SQL executed. So I assume in your service class You do something with this entity (use getter, log something) and that is why the output of these two methods looks the same.

ChlebikGitHub 和示例代码
很有帮助的问题#1
很有帮助的问题#2

这篇关于CrudRepository findOne() 和 JpaRepository getOne() 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆