我有以下课程结构:
我有一个用于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为每个具体类定义一个服务(bean)。
如果我运行测试,我会得到提到的异常:
WrongClassException - object with id was not of the specified subclass RegistrationCompound
我可以验证是否使用正确的compoundClass调用了正确的服务。但是,存储库似乎总是期望RegisterCompound。
我认为这是导致存储库自动装配的原因。我怀疑只创建了一个实例,该实例需要一个RegistrationCompound。我的问题是如何为每个服务类提供特定于类型的存储库?是否有可能拥有这样的通用存储库?
编辑:
现在我开始生气了。我想要的,我的设计,对我来说似乎非常基本。但是,每个这样的框架都使用了与示例中略有不同的框架,它只是打破了所有目的。我想知道人们如何将这个用于任何不完全简单的事情。
我确实按照遗嘱的建议重构某些事情。但是我仍然得到WrongClassException。问题是还有一个带有自定义行为的类AbstractCompoundRepositoryImpl。并且该类中的所有方法都会引发这种情况。很明显,spring仍然只创建了一个这样的实例(总是使用RegistrationCompound作为Type)。问题是这个类包含了我试图抽象出来的实际复杂的逻辑。如果必须为每个具体类别单独实现,则无法用于我的目的。我不明白。我告诉Spring要创建2个不同的存储库,所以请按照我告诉你的春天做什么?好?严重...
编辑2:
还有一些竞争条件。它并不总是与抛出此错误的测试相同,它根据复合类型弹簧决定用于创建存储库(而不是创建2,就像我告诉它要做的那样)而变化最大...
答案 0 :(得分: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;
}
}