我读到getOne()
是延迟加载的,并且findOne()
立即获取整个实体。我已经检查了调试日志,甚至在sql服务器上启用了监视以查看执行了哪些语句,我发现getOne()
和findOne()
都生成并执行相同的查询。但是,当我使用getOne()
时,这些值最初为null(当然,除了id)。
因此,谁能告诉我,如果两种方法都在数据库上执行相同的查询,那为什么我要在另一种方法上使用呢?我基本上是在寻找一种获取实体而不获取其所有子代/属性的方法。
编辑1:
Entity code
道代码:
@Repository
public interface FlightDao extends JpaRepository<Flight, Long> {
}
Debugging log findOne() vs getOne()
编辑2:
感谢Chlebik,我得以找到问题所在。就像Chlebik所说的那样,如果您尝试访问
getOne()
提取的实体的任何属性,则将执行完整查询。就我而言,我在调试时检查行为,一次只移动一行,但我完全忘记了在调试IDE时出于调试目的而尝试访问对象属性(或者至少是我认为的那样),因此调试触发器完整的查询执行。我停止调试,然后检查了日志,一切似乎都正常。getOne()
vs findOne()
(此日志来自MySQL general_log
,而不是休眠状态。Debugging log
No debugging log
最佳答案
这只是一个猜测,但是在“纯JPA”中,有一种称为getReference的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-Mike Keith和Merrick Schincariol编写的Pro JPA2-几乎每个段落都包含类似“行为取决于卖方”的内容。
编辑:
我已经设定好自己的设定。最终,我得出结论,如果您以任何方式干扰使用getOne提取的实体(甚至转到entity.getId()),都会导致SQL被执行。尽管如果仅使用它来创建代理(例如,如上面代码中所示的关系指示符),则什么也不会发生,也不会执行其他SQL。因此,我假设在您的服务类中您对此实体进行了某些操作(使用getter进行记录),这就是为什么这两种方法的输出看起来相同的原因。
ChlebikGitHub with example code
SO helpful question #1
SO helpful question #2