我正在建立一个具有以下结构的多模块spring-boot项目:
我正在尝试构建一个简单的spring boot应用程序,该应用程序会将示例记录保留在其h2 in-mem数据库中。但我不断收到以下错误:
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.****.***.services.testing.persistence.memory.MemoryTestingRepository' in your configuration.
我想念什么?
我尝试了以下方法:
JpaRepository
的单个接口即可,但是由于自定义方法,我必须具有接口层次结构,并且将来需要支持多个数据库实现。这是Handler类:
package com.***.**.services.testing.core;
@Service
public class TestingHandler {
@Autowired
private TestingRepository testingRepository;
@NotNull
public Testing create(@NotNull final TestingDto testingDto) {
Testing testing = new Testing("123", testingDto.getName(), testingDto.getDescription(), testingDto.Key(), testingDto.getVersion());
testingRepository.create(testing);
return testing;
}
}
请注意,它正在注入接口TestingRepository。
这是TestingRepository界面(简单明了):
package com.***.**.services.testing.persistence.api;
@Repository
public interface TestingRepository {
void create();
void findByCustomAttr();
}
这是TestingRepository的impl类:
package com.***.**.services.testing.persistence.memory;
@Repository
public abstract class MemoryTestingRepository implements JpaRepository<Testing, Integer>, TestingRepository {
@Override
public void create(@NotNull Testing testing) {
save(testing); //the real jpa method called.
}
@Override
public void findByCustomAttr(){
//some impl....
}
}
最后,主类如下所示:
package com.***.**.services.testing.main;
@SpringBootApplication(scanBasePackages = "com.***.**.services.testing")
@EnableJpaRepositories("com.***.**.services.testing.persistence")
@EntityScan(basePackages = {"com.***.**.services.testing.persistence"})
public class TestingApplication {
public static void main(String[] args) {
SpringApplication.run(TestingApplication.class, args);
}
}
我也有一个运行程序类,它调用处理程序方法:
package com.***.**.services.testing.main;
@Component
public class TestingService implements CommandLineRunner {
@Autowired
private TestingHandler testingHandler;
@Override
public void run(final String... args) throws Exception {
test();
}
public void test() {
testingHandler.create(new TestingDto("name", "desc", "some_mapping_id", Version.create()));
}
}
有指针吗?
答案 0 :(得分:0)
在我看来,不仅您的MemoryTestingRepository没有实现TestingRepository接口,而且还是抽象的,这让我有些困惑。那是实际代码还是您在发布时犯了一些编辑错误? 如果是,那么答案可能是Spring可能无法从抽象类创建bean。
查看文档https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.single-repository-behavior 解释了如何设置自定义存储库实现
编辑: 根据您的评论和更新,我现在了解您的问题。
您想要的是使您的具体存储库扩展SimplaJpaRepository,以便您的实现可以访问JpaRepository的save方法。
中查看示例您的存储库看起来像这样
package com.***.**.services.testing.persistence.memory;
@Repository
public class MemoryTestingRepository extends SimpleJpaRepository<Testing, Integer> implements TestingRepository {
@Override
public void create(@NotNull Testing testing) {
save(testing); //the real jpa method called.
}
@Override
public void findByCustomAttr(){
//some impl....
}
}
答案 1 :(得分:0)
您的MemoryTestingRepository
是抽象的,因此Spring不能实例化它。另外,存储库接口也由Spring Data Jpa管理,您不应在核心模块中具有该依赖性。
根据我在多模块项目中的经验(我很少接受),我目前在核心模块中为每个数据提供者请求创建SAM接口。然后在我的数据提供者模块中的具体数据提供者类中实现这些接口,并注入所需的JpaRepository。
对于您而言,这意味着:
核心模块:
@Service
public class TestingHandler {
@Autowired
private TestingCreator testingCreator;
@NotNull
public Testing create(@NotNull final TestingDto testingDto) {
Testing testing = ...;
testingCreator.createTesting(testing);
return testing;
}
}
public interface TestingCreator {
void createTesting(Testing testing);
}
持久性模块
@Repository
public class TestingDataprovider implements TestingCreator /*, ...other interfaces from core module*/ {
@Autowired
private TestingRepository testingRepository;
@Override
public void createTesting(Testing testing) {
testingRepository.save(testing);
}
// other methods like findByCustomAttr
}
public interface TestingRepository extends JpaRepository<Testing, Integer> {
// custom methods
}
通过这种方式,您还可以将核心实体与持久性实体分离。
作为参考,我发现最有用的指南是this github repository,它具有出色的自述文件以及其他有用的链接。