1

私は次のクラス構造を持っています:

クラス図

AbstractCompound用のスプリングデータリポジトリ(QueryDSLを使用)があります。

@Repository
public interface AbstractCompoundRepository<T extends AbstractCompound>
    extends JpaRepository<T, Long>, QueryDslPredicateExecutor<T> {
}

そして、そのリポジトリを呼び出すServiceクラス:

@Service
@Transactional
public class CompoundServiceImpl<T extends AbstractCompound>
    implements CompoundService<T> {

    @Autowired
    private AbstractCompoundRepository<T> compoundRepository;    

    private Class<T> compoundClass;

    private Class<? extends EntityPathBase<T>> compoundQueryClass;

    private PathBuilder<T> pathBuilder;   

    @Autowired
    public CompoundServiceImpl(Class<T> compoundClass,
            Class<? extends EntityPathBase<T>> compoundQueryClass) {
        this.compoundClass = compoundClass;
        this.compoundQueryClass = compoundQueryClass;
        String path = compoundClass.getSimpleName();
        pathBuilder = new PathBuilder<>(compoundClass, path);
    }       

    @Override
    public T findOne(Predicate predicate) {
        return compoundRepository.findOne(predicate);
    }
    //...snipped...
}

ApplicationContext.xmlは、具象クラスごとにservice(bean)を定義します。

テストを実行すると、前述の例外が発生します。

WrongClassException - object with id was not of the specified subclass RegistrationCompound

正しいcompoundClassで正しいサービスが呼び出されていることを確認できます。ただし、リポジトリは常にRegistrationCompoundを期待しているようです。

これがリポジトリの自動配線による原因だと思います。1つのインスタンスのみが作成され、そのインスタンスはRegistrationCompoundを予期していると思われます。私の質問は、サービスクラスごとにタイプ固有のリポジ​​トリを作成するにはどうすればよいですか?そのような一般的なリポジトリを持つことさえ可能ですか?

編集:

今、私は腹を立て始めています。私が欲しいもの、私のデザインは、私にとって非常に基本的なようです。しかし、そのようなフレームワークはすべて、例とは少し異なるものを使用しているため、すべての面で壊れています。完全に単純化されていないものに対して、人々が実際にこれをどのように使用するのだろうか。

willomeが提案したように、特定のことをリファクタリングしました。ただし、それでもWrongClassExceptionが発生します。重要なのは、カスタム動作を備えたクラスAbstractCompoundRepositoryImplもあるということです。そして、そのクラスのすべてのメソッドはその例外をスローします。Springがまだこれのインスタンスを1つだけ作成することは明らかなようです(常にRegistrationCompoundをTypeとして使用します)。問題は、このクラスに、抽象化しようとしている実際に複雑なロジックが含まれていることです。具象クラスごとにこれを個別に実装する必要がある場合、私の目的には使用できません。理解できません。春に2つの異なるリポジトリを作成するように指示しているので、春に指示したことを実行してください。Ok?真剣に...

編集2:

また、競合状態もあります。このエラーをスローするのは必ずしも同じテストではありません。リポジトリの作成にどのCompoundTypeSpringを使用するかによって最も確実に異なります(私が指示しているように2つ作成するのではなく...)

4

1 に答える 1

0

私もあなたの問題の原因が@autowiredリポジトリにあると思います。

私はあなたのコードをこのように変更したでしょう:

public abstract class AbstractCompoundService<T extends AbstractCompound>
implements CompoundService<T> {
  ...
  protected abstract AbstractCompoundRepository<T> getCompoundRepository();

  @Override
  public T findOne(Predicate predicate) {
    return getCompoundRepository().findOne(predicate);
  }
  ...
}
public RegistrationCompoundService extends AbstractCompoundService<RegistrationCompound> {

   @Autowired
   RegistrationCompoundRepository registrationCompoundRepository;

   protected AbstractCompoundRepository<RegistrationCompound> getCompoundRepository(){
      return registrationCompoundRepository;
   }
}
于 2013-02-06T12:06:54.107 に答える