2015-10-19 9 views
7

Ich lese, dass getOne() ist lazy geladen und findOne() holt das ganze Wesen sofort. Ich habe das Debugging-Protokoll überprüft und ich habe sogar die Überwachung auf meinem SQL-Server aktiviert, um zu sehen, welche Anweisungen ausgeführt werden. Ich habe festgestellt, dass sowohl getOne() als auch findOne() die gleiche Abfrage generiert und ausführt. Wenn ich jedoch getOne() verwende, sind die Werte anfangs null (außer für die ID natürlich).Unterschied zwischen CrudRepository findOne() und JpaRepository getOne()

Könnte mir bitte jemand sagen, wenn beide Methoden die gleiche Abfrage auf der Datenbank ausführen, warum sollte ich eine über die andere verwenden? Ich bin im Grunde auf der Suche nach einer Möglichkeit, eine Entität zu holen, ohne alle seine Kinder/Attribute zu bekommen.

EDIT1:

Entity code

Dao Code:

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

Debugging log findOne() vs getOne()

EDIT2:

Dank Chlebik konnte ich das Problem identifizieren. Wie Chlebik sagte, wenn Sie versuchen, auf eine Eigenschaft der Entität zuzugreifen, die von getOne() abgerufen wird, wird die vollständige Abfrage ausgeführt. In meinem Fall habe ich das Verhalten während des Debuggens überprüft und dabei Zeile um Zeile verschoben. Ich habe total vergessen, dass beim Debuggen der IDE versucht wird, auf Objekteigenschaften für Debugging-Zwecke zuzugreifen (oder zumindest das ist, was ich denke), also Debugging-Trigger die vollständige Abfrageausführung. Ich habe das Debuggen gestoppt und dann die Logs überprüft und alles scheint normal zu sein.

getOne() vs findOne() (Dieses Protokoll von MySQL genommen wird general_log und überwintert nicht.

Debugging log

No debugging log

Antwort

6

Es ist nur eine Vermutung, aber in 'reine JPA' gibt es ein Verfahren der EntityManager getReference.Es wurde entwickelt, um Entity mit nur ID in ihm zu erhalten.Seine Verwendung war hauptsächlich für die Angabe der Referenz vorhanden, ohne die gesamte Entität abrufen.Vielleicht die c Ode wird mehr sagen:

// 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); 

Ich gehe davon aus dann getOne dem gleichen Zweck dient. Warum sind die erzeugten Anfragen die gleichen, die Sie fragen? Nun, AFAIR in JPA Bibel - Pro JPA2 von Mike Keith und Merrick Schincariol - fast jeder Absatz enthält so etwas wie "das Verhalten hängt vom Anbieter".

BEARBEITEN:

Ich habe meine eigene Einrichtung eingestellt. Schließlich kam ich zu dem Schluss, dass, wenn Sie in irgendeiner Weise stören mit Entität mit getOne abgerufen (sogar für entity.getId() gehen) bewirkt, dass SQL ausgeführt wird. Wenn Sie es nur zum Erstellen eines Proxys verwenden (z. B. für einen Beziehungsindikator wie in einem Code oben gezeigt), passiert nichts, und es wird kein zusätzliches SQL ausgeführt. Ich nehme also an, dass Sie in Ihrer Serviceklasse etwas mit dieser Entität machen (benutzen Sie getter, loggen Sie etwas ein) und deshalb sieht die Ausgabe dieser beiden Methoden gleich aus.

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

+0

Dank für die Informationen. Was 'getOne()' tatsächlich tut, ist 'getReference()' aufzurufen. Ich bin wirklich verwirrt, weil, wie ich bereits erwähnt habe, beide Methoden die gleiche Abfrage generiert und ausgeführt haben! Vielleicht hat es mit MySQL zu tun, wie du es gesagt hast? Ich wünschte wirklich, dass jemand das bestätigen kann. Haben Sie eine Idee, ob die Abfrage in einem normalen Szenario zwischen den beiden Methoden unterschiedlich sein sollte? – prettyvoid

+0

Der Verkäufer meint nicht zB. MySQL aber Hibernate/TopLink/was auch immer Sie verwenden. Ich gehe davon aus, dass die Ausführung einer Anfrage auf definierten Beziehungen in Ihren Entitäten basiert und wahrscheinlich durch die JPA-Implementierung optimiert wird. IMHO mit einfacher Entität gibt es keinen großen Unterschied zwischen dem Abrufen des Handlers zu einer Entität (wie bei ** getReference **) und dem tatsächlichen Abrufen aller Daten. – Chlebik

+0

Ich muss eine Referenz bekommen, weil die Entitäten, die ich zu holen versuche, viele Sub-Entities haben, es ist eine Menge Arbeit das Ganze zu holen, wenn ich nur die ID der Entity benötige. Warten wir eine Weile, vielleicht kann uns jemand sagen, was passiert. Danke nochmal – prettyvoid

Verwandte Themen