2015-10-19 10 views
7

Przeczytałem, że getOne() jest leniwy załadowany i findOne() pobiera od razu cały obiekt. Sprawdziłem dziennik debugowania i nawet włączyłem monitorowanie na moim serwerze sql, aby zobaczyć, które instrukcje zostały wykonane. Stwierdziłem, że zarówno getOne(), jak i findOne() generują i wykonują to samo zapytanie. Jednak gdy używam getOne(), wartości są początkowo zerowe (z wyjątkiem oczywiście ID).Różnica między CrudRepository findOne() i JpaRepository getOne()

Czy ktoś mógłby mi powiedzieć, że jeśli obie metody wykonują to samo zapytanie w bazie danych, to dlaczego powinienem używać jednego na drugim? Zasadniczo szukam sposobu na pobranie obiektu bez uzyskiwania wszystkich jego elementów podrzędnych/atrybutów.

Edit1:

Entity code

kod Tao:

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

Debugging log findOne() vs getOne()

EDIT2:

Dzięki Chlebik udało mi się zidentyfikować problem. Jak powiedział Chlebik, jeśli spróbujesz uzyskać dostęp do jakiejkolwiek własności jednostki pobieranej przez getOne(), pełne zapytanie zostanie wykonane. W moim przypadku sprawdzałem zachowanie podczas debugowania, przesuwając jedną linię naraz, zupełnie zapomniałem, że podczas debugowania IDE próbuje uzyskać dostęp do właściwości obiektu w celu debugowania (lub przynajmniej tak to właśnie się dzieje), więc debugowanie wyzwala pełne wykonanie zapytania. Przestałem debugować, a następnie sprawdziłem logi i wszystko wyglądało normalnie.

getOne() vs findOne() (Ten dziennik jest pobierana z MySQL general_log i nie hibernacji.

Debugging log

No debugging log

Odpowiedz

6

To tylko przypuszczenie, ale w 'czystej JPA' nie jest metodą EntityManager o nazwie getReference. Jest on przeznaczony do pobierania elementu o tylko identyfikatorze, którego użycie służy głównie do wskazywania referencji bez potrzeby odzyskiwania całego obiektu. Ode powie więcej:

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

Zakładam następnie getOne służy temu samemu celowi. Dlaczego generowane zapytania są takie same, o jakie pytasz? Cóż, AFAIR w Biblii WZP - Pro JPA2 Mike'a Keitha i Merrick Schincariol - prawie każdy akapit zawiera coś w stylu "zachowanie zależy od sprzedawcy".

EDIT:

mam ustawić własną konfigurację. W końcu doszedłem do wniosku, że jeśli w jakikolwiek sposób ingerujesz w podmiot pobrany z getOne (nawet w przypadku entity.getId()) powoduje to wykonanie SQL. Chociaż jeśli używasz go tylko do tworzenia proxy (np. Dla wskaźnika relacji, jak pokazano w powyższym kodzie), nic się nie dzieje i nie jest wykonywany dodatkowy SQL. Zakładam więc, że w twojej klasie usługowej robisz coś z tym bytem (użyj getter, log coś) i dlatego wynik tych dwóch metod wygląda tak samo.

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

+0

Dzięki za informacje. Właściwie to, co robi 'getOne()', nazywa się 'getReference()'. Jestem bardzo zdezorientowany, ponieważ jak już wcześniej wspomniałem obie metody wygenerowały i wykonały to samo zapytanie! Więc może ma to związek z MySQL? Naprawdę chcę, żeby ktoś mógł to potwierdzić. Czy masz jakieś pojęcie, czy zapytanie powinno różnić się między dwiema metodami w normalnym scenariuszu? – prettyvoid

+0

Dostawca nie oznacza np. MySQL, ale Hibernate/TopLink/cokolwiek używasz. Zakładam, że realizowana kwerenda opiera się na zdefiniowanych relacjach w Twoich podmiotach i prawdopodobnie optymalizacji wykonanej przez implementację JPA. IMHO z prostą jednostką nie ma dużej różnicy między pobieraniem handler'a do encji (jak z ** getReference **) i rzeczywistym pobieraniem wszystkich danych. – Chlebik

+0

Muszę uzyskać odwołanie, ponieważ podmioty, które próbuję pobrać, mają wiele pod-encji, to dużo pracy, aby pobrać całość, gdy potrzebuję tylko identyfikatora jednostki. Poczekaj chwilę, może ktoś może nam powiedzieć, co się dzieje. Jeszcze raz dziękuję – prettyvoid