1

我有以下类结构:

类图

我有一个用于 AbstractCompound 的 spring-data 存储库(使用 QueryDSL):

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

以及调用该存储库的服务类:

@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 为每个具体类定义了一个服务(bean)。

如果我运行测试,我会得到提到的异常:

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

我可以验证是否使用正确的复合类调用了正确的服务。然而,存储库似乎总是期待一个 RegistrationCompound。

我认为这是由于自动装配存储库的原因。我怀疑只创建了一个实例,并且该实例需要一个 RegistrationCompound。我的问题是如何为每个服务类创建一个特定类型的存储库?甚至有可能拥有这样一个通用存储库吗?

编辑:

现在我开始生气了。我想要的,我的设计,对我来说似乎很基本。但是,每个这样的框架使用的任何东西都与示例中的略有不同,它只是在各个方面都中断了。我想知道人们实际上如何将它用于任何不完全简单的事情。

我确实按照 willome 的建议重构了某些东西。但是我仍然得到 WrongClassException。问题是还有一个具有自定义行为的 Class AbstractCompoundRepositoryImpl。并且该类中的所有方法都会抛出该异常。很明显,spring 仍然只创建 1 个实例(始终使用 RegistrationCompound 作为类型)。问题是这个类包含我试图抽象出来的实际复杂的逻辑。如果必须为每个具体类单独实现它,那么它对于我的目的是不可用的。我不明白。我告诉 spring 创建 2 个不同的存储库,所以请按照我告诉你的 spring 做?好的?严重地...

编辑2:

还有一些比赛条件。引发此错误的测试并不总是相同的,它肯定会根据 spring 决定用于创建存储库的复合类型而有所不同(而不是像我告诉它那样创建 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 回答