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

查看:662
本文介绍了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.

实体代码

Dao代码:

@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()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-Mike Keith和Merrick Schincariol的 Pro JPA2 -几乎每个段落都包含类似行为取决于供应商"的内容.

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
SO有用的问题#2

ChlebikGitHub with example code
SO helpful question #1
SO helpful question #2

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

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