Zaglądam do Spring Data JPA. Rozważ poniższy przykład, w którym otrzymam wszystkie funkcje Crud i Finder działające domyślnie, a jeśli chcę dostosować wyszukiwarkę, można to również łatwo zrobić w samym interfejsie.
@Transactional(readOnly = true)
public interface AccountRepository extends JpaRepository<Account, Long> {
@Query("<JPQ statement here>")
List<Account> findByCustomer(Customer customer);
}
Chciałbym wiedzieć, jak mogę dodać kompletną niestandardową metodę z jej implementacją dla powyższego AccountRepository? Ponieważ jest to interfejs, nie mogę tam zaimplementować metody.
źródło
AccountRepositoryImpl
nie :,AccountRepositoryCustomImpl
itd. - to bardzo ścisła konwencja nazewnicza.Error creating bean with name 'accountRepositoryImpl': Bean with name 'accountRepositoryImpl' has been injected into other beans [accountRepository] in its raw version as part of a circular reference, but has eventually been wrapped.
QueryDslRepositorySupport
Musisz również wstrzyknąć repozytorium przez wstrzyknięcie pola lub ustawiającego zamiast wstrzyknięcia konstruktora, w przeciwnym razie nie będzie w stanie utworzyć fasoli. Wydaje się, że to działa, ale rozwiązanie wydaje się nieco „brudne”, nie jestem pewien, czy są jakieś plany poprawy tego działania ze strony zespołu Spring Data.Oprócz axtavt za odpowiedź , nie zapomnij można wstrzykiwać Entity Manager w implementacji niestandardowych jeśli jest to potrzebne do budowania zapytań:
źródło
Zaakceptowana odpowiedź działa, ale ma trzy problemy:
AccountRepositoryImpl
. Dokumentacja wyraźnie stwierdza, że ma się nazywaćAccountRepositoryCustomImpl
, nazwa zwyczaj Interface PlusImpl
@Autowired
, które są uważane za złą praktykęZnalazłem sposób, aby uczynić go idealnym, ale nie bez użycia innej nieudokumentowanej funkcji Spring Data:
źródło
accountRepositoryBasic
). W przeciwnym razie wiosna narzekała, że są 2 fasole do wstrzyknięcia do mojego*Impl
konstruktora.AccountRepositoryBasic
iAccountRepositoryCustom
będą dostępne przez wstrzyknięcieAccountRepository
Jest to ograniczone w użyciu, ale w przypadku prostych metod niestandardowych można użyć domyślnych metod interfejsu, takich jak:
EDYTOWAĆ:
W tym wiosennym samouczku jest napisane:
Można więc po prostu zadeklarować taką metodę jak:
a jeśli obiekt
Hobby
jest własnością Klienta, Spring automatycznie zdefiniuje dla Ciebie metodę.źródło
Używam następującego kodu, aby uzyskać dostęp do wygenerowanych metod wyszukiwania z mojej niestandardowej implementacji. Przeprowadzenie wdrożenia przez fabrykę fasoli zapobiega problemom z tworzeniem okrągłych ziaren.
źródło
Jak określono w udokumentowanej funkcjonalności ,
Impl
przyrostek pozwala nam mieć czyste rozwiązanie:@Repository
interfejsie, powiedzmyMyEntityRepository
, metody Spring Data lub metody niestandardoweMyEntityRepositoryImpl
(Impl
przyrostek jest magią) w dowolnym miejscu (nawet nie musi znajdować się w tym samym pakiecie), która implementuje tylko metody niestandardowe i dodaj adnotację do takiej klasy za pomocą@Component
** (@Repository
nie zadziała).MyEntityRepository
za pośrednictwem@Autowired
do użytku w metodach niestandardowych.Przykład:
Klasa podmiotu:
Interfejs repozytorium:
Bean implementacji metod niestandardowych:
Małe wady, które zidentyfikowałem, to:
Impl
klasie są oznaczane przez kompilator jako nieużywane, stąd@SuppressWarnings("unused")
sugestia.Impl
klasy. (Podczas gdy w standardowej implementacji interfejsów fragmentów dokumenty sugerują , że możesz mieć ich wiele).źródło
MyEntityRepository
, a nie*Impl
.Jeśli chcesz mieć możliwość wykonywania bardziej wyrafinowanych operacji, możesz potrzebować dostępu do wewnętrznych elementów Spring Data, w którym to przypadku działa (jako moje tymczasowe rozwiązanie do DATAJPA-422 ):
źródło
Biorąc pod uwagę fragment kodu, pamiętaj, że możesz przekazać obiekty natywne tylko do metody findBy ###, powiedzmy, że chcesz załadować listę kont należących do określonych klientów, jednym z rozwiązań jest to zrobić,
Spraw, aby nazwa tabeli, o którą chcesz zapytać, jest taka sama jak klasa Entity. Aby zapoznać się z dalszymi wdrożeniami, spójrz na to
źródło
Jest jeszcze jedna kwestia do rozważenia. Niektórzy ludzie oczekują, że dodanie niestandardowej metody do repozytorium automatycznie ujawni je jako usługi REST pod linkiem „/ search”. Tak niestety nie jest. Spring obecnie tego nie obsługuje.
Jest to funkcja `` zgodnie z projektem '', reszta danych sprężynowych wyraźnie sprawdza, czy metoda jest metodą niestandardową i nie ujawnia jej jako linku wyszukiwania REST:
Oto wypowiedź Olivera Gierke:
Więcej szczegółów można znaleźć w tym numerze: https://jira.spring.io/browse/DATAREST-206
źródło
@RestResource(path = "myQueryMethod")
adnotację do metody. Powyższy cytat po prostu stwierdza, że Spring nie wie, jak chcesz go zmapować (np. GET vs POST itp.), Więc to do Ciebie należy określenie tego za pomocą adnotacji.Dodanie niestandardowego zachowania do wszystkich repozytoriów:
Aby dodać niestandardowe zachowanie do wszystkich repozytoriów, należy najpierw dodać interfejs pośredni, aby zadeklarować zachowanie współdzielone.
Teraz Twoje indywidualne interfejsy repozytorium rozszerzą ten interfejs pośredni zamiast interfejsu repozytorium, aby uwzględnić zadeklarowaną funkcjonalność.
Następnie utwórz implementację interfejsu pośredniego, który rozszerza klasę bazową repozytorium specyficzną dla technologii trwałości. Ta klasa będzie następnie działać jako niestandardowa klasa bazowa dla serwerów proxy repozytorium.
Spring Data Repositories Część I. Odniesienie
źródło
Rozszerzam SimpleJpaRepository:
i dodaje tę klasę do @EnableJpaRepositoryries repositoryBaseClass.
źródło