java - UnsatisfiedDependencyException 和循环依赖
问题描述
我正在尝试构建和运行一些 Spring Boot 遗留代码,但它失败了:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataLoader' defined in file [......\bootstrap\DataLoader.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'organizationServiceImpl': Unsatisfied dependency expressed through method 'setAssessmentService' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'assessmentServiceImpl': Invocation of init method failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
......
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'organizationServiceImpl': Unsatisfied dependency expressed through method 'setAssessmentService' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'assessmentServiceImpl': Invocation of init method failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:676)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at ........
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'assessmentServiceImpl': Invocation of init method failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:139)
DataLoader 类是:
@Component
public class DataLoader implements ApplicationRunner {
private final OrganizationService organizationService;
private List<String> organizationNames = Arrays.asList(
...some long list of string literals...
);
public DataLoader(OrganizationService organizationService) {
this.organizationService = organizationService;
}
@Override
public void run(ApplicationArguments args) {
if (CollectionUtils.isEmpty(organizationService.findAll())) {
addOrganizations();
}
}
private void addOrganizations() {
organizationNames.forEach(name -> {
OrganizationRequest organization = new OrganizationRequest();
organization.setName(name);
if (
....irrelevant code....
}
organizationService.save(organization);
});
}
}
和 OrganizationServiceImpl 类是:
@Service
public class OrganizationServiceImpl implements OrganizationService {
private final OrganizationRepository organizationRepository;
private final AddressService addressService;
private final ContactService contactService;
private final SupplierQualifierService supplierQualifierService;
private final MonitoringScopeService monitoringScopeService;
private final FinancialService financialsService;
private DocumentService documentService;
private AssessmentService assessmentService;
@Getter
private Map<Long, Set<QuestionType>> questionTypesForAssessmentByOrganization = new HashMap<>();
public OrganizationServiceImpl(OrganizationRepository organizationRepository, AddressService addressService, ContactService contactService, SupplierQualifierService supplierQualifierService, MonitoringScopeService monitoringScopeService, FinancialService financialsService ) {
this.organizationRepository = organizationRepository;
this.addressService = addressService;
this.contactService = contactService;
this.supplierQualifierService = supplierQualifierService;
this.monitoringScopeService = monitoringScopeService;
this.financialsService = financialsService;
}
//workaround for circular dependency
@Autowired
public void setAssessmentService(AssessmentService assessmentService) {
this.assessmentService = assessmentService;
}
// to prevent circular dependency problem ...
@Autowired
public void setDocumentService(DocumentService documentService) {
this.documentService = documentService;
}
@Override
public Organization findById(Long id) {
Optional<Organization> organization = organizationRepository.findById(id);
return organization.orElse(new Organization());
}
@Override
public List<Organization> findAll() {
return organizationRepository.findAll();
}
@Override
public Organization save(OrganizationRequest request) {
....long not relevant code...
return savedOrganization;
}
....long not relevant code, some business logic...
}
AssessmentServiceImpl 类是:
@Service
public class AssessmentServiceImpl implements AssessmentService {
private final AssessmentRepository assessmentRepository;
private final OrganizationService organizationService;
private final AnswerService answerService;
private final QuestionService questionService;
private Map<QuestionType, Integer> numberOfQuestionsByType = new HashMap<>();
public AssessmentServiceImpl(AssessmentRepository assessmentRepository, OrganizationService organizationService, AnswerService answerService, QuestionService questionService) {
this.assessmentRepository = assessmentRepository;
this.organizationService = organizationService;
this.answerService = answerService;
this.questionService = questionService;
}
@PostConstruct
public void postConstruct() {
for (QuestionType type : QuestionType.values()) {
numberOfQuestionsByType.put(type, questionService.findByQuestionType(type).size());
}
}
... some business logic code....
}
失败的依赖注入链是:
Error creating bean with name 'dataLoader':
Error creating bean with name 'organizationServiceImpl':
Error creating bean with name 'assessmentServiceImpl':
但我看不出有直接原因。
我看到原始开发人员遇到了循环依赖问题,但从我的谷歌搜索来看,这似乎是合适的解决方案:
//workaround for circular dependency
@Autowired
public void setAssessmentService(AssessmentService assessmentService) {
this.assessmentService = assessmentService;
}
// to prevent circular dependency problem ...
@Autowired
public void setDocumentService(DocumentService documentService) {
this.documentService = documentService;
}
解决方案
错误消息指出,在创建 bean 时,它的数据源有问题:
InvalidDataAccessResourceUsageException:无法提取 ResultSet
我怀疑读取数据库时出现问题。不存在循环依赖问题。这是一个完美的创豆链。Spring 检测到循环依赖并显示不同的错误消息。
尝试取消注释 @PostConstruct 中的代码并再次运行应用程序。
@PostConstruct
public void postConstruct() {
for (QuestionType type : QuestionType.values()) {
numberOfQuestionsByType.put(type,
questionService.findByQuestionType(type).size());
}
}
推荐阅读
- flutter - 搜索栏实现不起作用。代码不搜索任何东西
- r - R; 想要制作一个漂亮的分组条形图(ggplot2),y 轴上有 %,x 轴上有类别(总共 9 个),每个类别有四个分组条
- react-native - React-Native 渲染一个有 2 行的水平列表
- docker - 运行 Docker nginx 找不到复制的文件
- postgresql - sqlalchemy 无法在 for 循环中执行 session.add()
- bootstrap-table - 引导表不适用于 RouterLink
- javascript - 在 Golang/Gin 模板中运行 Vue 应用程序
- android - 我如何在颤动中创建一个绘图应用程序,我可以在颤动中绘制线条形状
- python - scipy.stats.binom 和 np.random.binomial 之间的区别
- angular - Primeng virtualscroll offset 像 peagination