2013-02-27 11 views
14

Ja próbuje uzyskać odniesienie do mojego repozytorium interfejsu (UserRepository), która rozciąga CrudRepository w moim realizacji niestandardowych (UserRepositoryExtensionImpl) w celu uzyskania dostępu do wszystkich metod przewidzianych przez wiosennej WZP.CrudRepository wewnątrz mojego niestandardowego wdrożenia repozytorium

Crud Rozszerzenie: Interfejs

@Repository 
public interface UserRepository extends CrudRepository<User, String>, UserRepositoryExtension<RosterUser> { 
    ...any custom spring JPA methods... 
} 

Rozszerzenie:

@Repository 
public interface UserRepositoryExtension <T> { 
    public T put(T entity); 
} 

klienta Realizacja:

public class UserRepositoryExtensionImpl implements UserRepositoryExtension<User> { 

    UserRepository userRepository; 

    @Autowired 
    public UserRepositoryExtensionImpl(UserRepository userRepository) { 
     this.userRepository = userRepository; 
    } 

    @Override 
    public User put(User user) { 
     System.out.println(user + "was put"); 
     // ...put logic here 
     return null; 
    }... 
} 

Jednak jestem w stanie wstrzyknąć UserRepository od kołową zależność istnieje (biorąc pod uwagę, że UserRepository rozszerza interfejs implementowany przez mój UserRepositoryImpl). Ja otrzymuję następujący błąd:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ' userRepositoryImpl': Requested bean is currently in creation: Is there an unresolvable circular  reference? 

Możliwe, ale mniej niż idealnym rozwiązaniem byłoby, aby wstrzyknąć i EntityManager do UserRepositoryImp, ale w tym przypadku nie mam dostępu do żadnej z metod Wiosna WZP świadczonych przez CrudRepository lub dodatkowe metody, które mogłem utworzyć w UserRepository.

Wszelkie sugestie, jak to obejść?

Każda pomoc zostanie bardzo doceniona.

EDIT: Jak wspomniano w odpowiedzi @ Shelley, udało mi się rozwiązać ten problem poprzez 3 zmiany:

  • Wyjmowanie @Repository od UserRepositoryExtensionImpl
  • zmiana nazwy UserRepositoryExtensionImpl do UserRepositoryImpl. Wygląda na to, że Spring wie o istnieniu implementacji. Zobacz Spring Doc
  • Usunięcie mojego konstruktora i przesuwając @Autowired pola userRepository

sukces!

+0

Jeśli nie ma żadnych rzeczywista zależność cykliczna (tj: Wiosna prostu się mylić, ponieważ uważa, że ​​masz wiele ziaren o podobnym charakterze). Dodaj dodatkowy kwalifikator, taki jak identyfikator komponentu bean, aby Spring wiedział, która komponent bean będzie automatycznie programowany. – gerrytan

+0

daj nam kontekst wiosennej aplikacji – Elbek

+1

@gerrytan - Mogę się mylić, ale myślę, że istnieje zależność cykliczna. FYI: Ten sam problem jest przywoływany [tutaj] (http://forum.springsource.org/showthread.php?132889-Spring-Data-Calling-default-CRUD-metody-inside-i-standard-repository-implementation&p= 439701 # post439701) –

Odpowiedz

9

Parę małych rzeczy muszą zostać zmienione, aby to zadziałało:

  • Zdjąć @Repository adnotacji z interfejsu zwyczaj repozytorium (UserRepositoryExtension).

  • Realizacja niestandardowego repozytorium powinna w rzeczywistości być nazwana "<StandardRepository>Impl" zamiast "<CustomRepository>Impl". W swoim przykładzie kodu powinno to być UserRepositoryImpl zamiast UserRepositoryExtensionImpl.

+0

Dzięki @shelley! Twoja sugestia, oprócz przeniesienia '@ Autowired' z konstruktora, do pola' userRepository' rozwiązała problem. Mogę teraz odwoływać się do 'UserRepository' w mojej implementacji niestandardowej. :) –

0

Istnieje well defined way to create custom repository implementations in Spring Data JPA, którego należy przestrzegać. Zasadniczo musisz rozszerzyć CrudRepository, aby nie trzeba było wstawiać jego instancji do niestandardowej implementacji.

+0

Myślę, że OP stosuje się do tego podejścia, ale chciałby użyć metod ze standardowego komponentu bean repozytorium w ramach implementacji niestandardowego repozytorium. – shelley

+0

@zagyi, Shelley ma rację. Staram się postępować zgodnie z tym samym podejściem, które sugeruje Spring, iw ten sposób znalazłem się w sytuacji, w której jestem. Dodam więcej szczegółów do tego pytania, aby wyjaśnić tę kwestię. –

+0

@shelley, @ Julian: Przepraszam, po uważnym przeczytaniu tego pytania, jest jasne, że źle to zrozumiałem. Myślę jednak, że to dziwne, co Julian próbuje zrobić. Zwykle jest to klasa usług, w której można wstawiać instancje repozytorium i wdrażać metody wyższego poziomu, które wywołują jedną lub więcej operacji repozytorium. Sprawdź, czy sensownym rozwiązaniem byłoby przeniesienie logiki 'put()' o jeden poziom wyżej do interfejsu/klasy usług. – zagyi

0

że rozwiązali problem poprzez wstrzykiwanie ApplicationContext i uzyskania ziarna leniwie sposób używając applicationContext.getBean(UserRepository.class). Działa to w ten sposób.

4

Jak zauważył Shelley, nazywanie jest bardzo ważne, aby praca z autowirem działała. W poniższym przykładzie podążam za właściwym standardem nazewnictwa dla mojego własnego interfejsu i jego implementacji. Ale mój interfejs rozszerzony o JpaRepository został nazwany "ItemDao" zamiast "ItemRepository", co spowodowało, że ta wiosna całkowicie zignorowała moją niestandardową implementację ...

OBS !!! Powinno być „ItemRepository”

@Repository 
public interface ItemDao extends JpaRepository<Item, Long>, ItemRepositoryCustom {} 

mój interfejs

interface ItemRepositoryCustom {...} 

moja klasa realizacja

class ItemRepositoryImpl implements ItemRepositoryCustom {...} 

Jeśli ktoś ma podobne problemy, zacznij od następujących standard nazewnictwa, który jest używany w dokumentacji wiosny pod linkiem poniżej.

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations

+1

Chciałbym, aby takie szczegóły zostały wspominane bardziej wyraźnie ... Ale tak, nazywanie wydaje się dość ważne. Cieszę się, że udało ci się to rozgryźć! –

+1

Ja, kiedy czytasz fragment dokumentacji bez wcześniejszej znajomości wiosennej, nie ma sposobu, aby dowiedzieć się, jak ścisła jest reguła nazewnictwa. – Olle89

Powiązane problemy