春のデータの素晴らしさに触発されて、多くのコントローラーに拡張できる抽象的なRESTControllerを作成したいと思いました。次のクラスを作成しました。
@Controller
public abstract class RESTController<E, PK extends Serializable, R extends PagingAndSortingRepository<E, PK>>
{
@Autowired
private R repository;
@RequestMapping(method=RequestMethod.GET, params={"id"})
@ResponseBody
public E getEntity(@RequestParam PK id)
{
return repository.findOne(id);
}
...
}
ジェネリックがリポジトリで@Autowiredを許可することを期待していましたが、次のエラーが発生します。
SEVERE: Allocate exception for servlet appServlet
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.data.repository.PagingAndSortingRepository] is defined: expected single matching bean but found 3: [groupRepository, externalCourseRepository, managedCourseRepository]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:800)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
エラーが何を示しているかを理解しています。@Autowiredには複数の一致があります。次のコントローラーを作成することで機能すると思ったので、混乱しています。
@Controller
@RequestMapping(value="/managedCourse")
public class ManagedCourseController extends RESTController<ManagedCourse, Long, ManagedCourseRepository>
{
...
}
これは、RESTControllerで次のようなメソッドを使用することで回避するのに十分簡単です。
protected abstract R getRepository();
次に、実装クラスでこれを実行します。
@Autowired
private ManagedCourseRepository repository;
@Override
protected ManagedCourseRepository getRepository()
{
return repository;
}
どうすればこれを機能させることができるかについて誰かが考えているのではないかと思っていました。
また、私はこの興味深いアリクルを見つけました。