Как должна быть организована структура каталогов для SpringBoot MongoDB CrudRepositoryCustom Реализация? - PullRequest
0 голосов
/ 31 августа 2018

Я создал простой проект maven, используя SpringBoot и MongoDB. У меня есть две реализации репозитория, то есть StudentRepository и StudentRepositoryCustom . StudentRepository распространяется на встроенный MongoRepository и пользовательский репозиторий. Пользовательские методы хранилища реализованы в StudentRepositoryImpl . Приложения запускаются без ошибок, когда я помещаю StudentRepository , StudentRepositoryCustom и StudentRepositoryImpl в один и тот же пакет, т.е. com.aman.springboot.repository . Но приложение выдает ошибку, когда класс реализации перемещается в какой-то другой пакет, скажем, com.aman.springboot.impl .

Что я делаю не так?

Вот основной класс:

package com.aman.springboot.client;

@SpringBootApplication(scanBasePackages = "com.aman.springboot") 
public class ApplicationLauncher {
    public static void main(String[] args) {
        SpringApplication.run(StudentController.class, args);
    }
}

Вот класс RestController:

package com.aman.springboot.controller;

@RestController
@EnableAutoConfiguration
@EnableMongoRepositories(basePackages = "com.aman.springboot.repository")
@RequestMapping(value = "/student")
public class StudentController {

    @Autowired
    private StudentRepository studentRepository;

    @RequestMapping(value = "/getStudent", method = RequestMethod.GET)
    public StudentRepo getStudent(@RequestParam(required = true) int id) {
        return studentRepository.findStudentById(id);
    }

    @RequestMapping(value = "/removeStudent", method = RequestMethod.POST)
    public void removeStudent(@RequestBody(required = true) StudentRepo 
        studentRepo) {
        studentRepository.deleteStudent(studentRepo);
    }
}

Вот репозиторий студентов:

package com.aman.springboot.repository;

@Repository
public interface StudentRepository extends MongoRepository<StudentRepo, 
    String>, StudentRepositoryCustom {      
    public StudentRepo findStudentById(int id);
}

Вот студенческий репозиторий. Пользовательский:

package com.aman.springboot.repository;

public interface StudentRepositoryCustom {
    public void deleteStudent(StudentRepo studentRepo);
}

Вот StudentRepositoryImpl:

package com.aman.springboot.impl;

@Service
public class StudentRepositoryImpl implements StudentRepositoryCustom{

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private StudentRepo student;

    @Override
    public void deleteStudent(StudentRepo studentRepo) {
        mongoTemplate.remove(studentRepo);
    }
}

Как видите, оба интерфейса или репозитории находятся в одном пакете, но класс реализации интерфейса StudentRepositoryCustom находится в другом пакете. В этом случае приложение выдает ошибку при развертывании:

Вот трассировка стека:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error 
creating bean with name 'studentController': Unsatisfied dependency 
expressed through field 'studentRepository'; nested exception is 
org.springframework.beans.factory.BeanCreationException: Error creating bean 
with name 'studentRepository': Invocation of init method failed; nested 
exception is org.springframework.data.mapping.PropertyReferenceException: No 
property deleteStudent found for type StudentRepo!  at 
org.springframework.beans.factory.annotation. 
AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject 
(AutowiredAnnotationBeanPostProcessor.java:586) 
~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE]     at 
org.springframework.beans.factory.annotation.InjectionMetadata.inject 
(InjectionMetadata.java:91) ~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE]      
at 
org.springframework.beans.factory.annotation. 
AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues 
(AutowiredAnnotationBeanPostProcessor.java:372) ~[spring-beans- 
5.0.8.RELEASE.jar:5.0.8.RELEASE]    at 
.
.
.
.
org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) 
[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]   at 
com.aman.springboot.client.ApplicationLauncher.main 
(ApplicationLauncher.java:17) [classes/:na] 

Caused by: org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'studentRepository': Invocation of init method 
failed; nested exception is 
org.springframework.data.mapping.PropertyReferenceException: No property 
deleteStudent found for type StudentRepo!   at 
org.springframework.beans.factory.support. 
AbstractAutowireCapableBeanFactory.initializeBean 
(AbstractAutowireCapableBeanFactory.java:1699) ~[spring-beans- 
5.0.8.RELEASE.jar:5.0.8.RELEASE]    at 
.
.
.
.
tializeBean(AbstractAutowireCapableBeanFactory.java:1695) ~[spring-beans- 
5.0.8.RELEASE.jar:5.0.8.RELEASE]    ... 29 common frames omitted

Приложение работает нормально, если я переместил класс StudentRepositoryImpl в пакет, в котором находятся репозитории, т.е. com.aman.springboot.repository .

Любая помощь будет оценена !!! Спасибо.

1 Ответ

0 голосов
/ 04 сентября 2018

Я решил свою проблему путем рефакторинга структуры пакета для пользовательского репозитория и его класса реализации. Из этой проблемы я понимаю, что Spring ищет реализованные классы для репозиториев в дочерних пакетах.
Например, если хранилище определено в com.foo.repo , класс его реализации должен быть в com.foo.repo.impl .
Репозитории должны быть определены в пакетах верхнего уровня, а реализующий класс должен быть в том же пакете или в его дочернем пакете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...