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