20

Spring JPAが提供するすべてのメソッドにアクセスするために、カスタム実装()内UserRepositoryで拡張されたリポジトリインターフェース()への参照を取得しようとしています。CrudRepositoryUserRepositoryExtensionImpl

Crud Extension:

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

拡張インターフェース:

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

カスタム実装:

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;
    }...
}

UserRepositoryただし、循環依存関係が存在するため、注入できません( UserRepositorymyによって実装されたインターフェイスを拡張する場合UserRepositoryImpl)。次のエラーが発生します。

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

可能ですが、理想的とは言えない解決策は、に注入して注入することEntityManagerですUserRepositoryImpが、その場合、によって提供されるSpring JPAメソッドCrudRepository、またはUserRepositoryで作成した可能性のある追加のメソッドにアクセスできません。

これを回避する方法について何か提案はありますか?

どんな助けでも大歓迎です。

編集:@shelleyの回答で述べたように、私は3つの変更を加えることでこれを解決することができました:

  • @Repositoryからの削除UserRepositoryExtensionImpl
  • に名前を変更UserRepositoryExtensionImplUserRepositoryImplます。どうやらこれはSpringに実装の存在を認識させます。SpringDocを参照してください
  • コンストラクターを削除@Autowiredして、userRepositoryフィールドに移動します

成功!

4

6 に答える 6

12

これを機能させるには、いくつかの小さな変更が必要です。

  • @Repositoryカスタムリポジトリインターフェイスから注釈を削除します( UserRepositoryExtension)。

  • カスタムリポジトリの実装には、実際には「<StandardRepository>Impl」ではなく「」という名前を付ける必要があります<CustomRepository>Impl。コード例では、これはUserRepositoryImplの代わりになりUserRepositoryExtensionImplます。

于 2013-02-28T17:00:42.183 に答える
4

シェリーが指摘したように、オートワイヤーを機能させるには命名が非常に重要です。以下の例では、カスタムインターフェイスとその実装の正しい命名基準に従います。しかし、JpaRepositoryを拡張した私のインターフェースは、「ItemRepository」ではなく「ItemDao」という名前でした。その結果、その春は私のカスタム実装を完全に無視しました...

OBS !!! 「ItemRepository」である必要があります

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

私のインターフェース

interface ItemRepositoryCustom {...}

私の実装クラス

class ItemRepositoryImpl implements ItemRepositoryCustom {...}

誰かが同様の問題を抱えている場合は、以下のリンクにある春のドキュメントで使用されている命名基準に従うことから始めてください。

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

于 2013-05-21T07:31:25.703 に答える
0

SpringDataJPAでカスタムリポジトリの実装を作成するための明確に定義された方法があります。これに従う必要があります。基本的には拡張する必要があるCrudRepositoryため、カスタム実装にインスタンスを挿入する必要はありません。

于 2013-02-28T07:50:30.187 に答える
0

ApplicationContextを使用して、怠惰な方法でBeanを注入して取得することで問題を解決しapplicationContext.getBean(UserRepository.class)ました。このように機能します。

于 2013-02-28T21:29:20.590 に答える
0

私はそれをする必要なしにそれを行う方法を見つけました@Autowire

public interface UserRepository extends 
    UserRepositoryBasic,
    UserRepositoryExtension 
{ 
}

public interface UserRepositoryBasic extends
    JpaRepository<User, String>
{
    // standard Spring Data methods, like findByLogin
}

public interface UserRepositoryExtension 
{
    public void customMethod();
}

public class UserRepositoryExtensionImpl implements
    UserRepositoryExtension 
{
    private final UserRepositoryBasic userRepositoryBasic;

    // constructor-based injection
    public UserRepositoryExtensionImpl(
        UserRepositoryBasic userRepositoryBasic)
    {
        this.userRepositoryBasic = userRepositoryBasic;
    }

    public void customMethod() 
    {
        // we can call all basic Spring Data methods using
        // userRepositoryBasic
    }
}
于 2018-07-30T22:43:59.310 に答える
0

この場合、@Lazy注釈を使用することをお勧めします。

public class MyCustomRepositoryImpl implements MyCustomRepository {

    @Lazy
    @Autowired
    private MyRepository myRepository;

    @Override
    public boolean customMethod() {
       return myRepository.count() > 0;
    }

}

コンストラクターパラメーターを使用して、Springは「基本」リポジトリを必要とする「基本」リポジトリクラスを作成しようとします。これには「基本」リポジトリが必要です。これは循環依存の典型的なケースです。

なし@Lazyでは、それだけでは@Autowired機能しません(基本リポジトリのファクトリBeanに問題があります)。

@Lazyこの場合、これが最もエレガントなソリューションだと思います。

于 2018-12-17T14:34:10.880 に答える