不满意依赖项异常:创建名称为 'contactService' 的 Bean 时出错



我正在使用MongoDB作为数据库进行Spring Boot项目。我不知道为什么每次尝试运行此noDuplicateEmail测试时都会不断出现此错误。
错误消息

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'contactService' defined in file [/Users/gs97ahn/Development/spring-workspace/gabojait-spring/out/production/classes/com/inuappcenter/gabojaitspring/user/service/ContactService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactRepository' defined in com.inuappcenter.gabojaitspring.user.repository.ContactRepository defined in @EnableMongoRepositories declared on MongodbConfiguration: Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoTemplate' defined in class path resource [com/inuappcenter/gabojaitspring/config/MongodbConfiguration.class]: Unsatisfied dependency expressed through method 'mongoTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDbFactory' defined in class path resource [com/inuappcenter/gabojaitspring/config/MongodbConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.MongoDatabaseFactory]: Factory method 'mongoDbFactory' threw exception; nested exception is java.lang.IllegalArgumentException: state should be: databaseName does not contain '/'
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactRepository' defined in com.inuappcenter.gabojaitspring.user.repository.ContactRepository defined in @EnableMongoRepositories declared on MongodbConfiguration: Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoTemplate' defined in class path resource [com/inuappcenter/gabojaitspring/config/MongodbConfiguration.class]: Unsatisfied dependency expressed through method 'mongoTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDbFactory' defined in class path resource [com/inuappcenter/gabojaitspring/config/MongodbConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.MongoDatabaseFactory]: Factory method 'mongoDbFactory' threw exception; nested exception is java.lang.IllegalArgumentException: state should be: databaseName does not contain '/'

测试

import com.inuappcenter.gabojaitspring.user.domain.Contact;
import com.inuappcenter.gabojaitspring.user.dto.ContactDefaultResponseDto;
import com.inuappcenter.gabojaitspring.user.dto.ContactSaveRequestDto;
import com.inuappcenter.gabojaitspring.user.service.ContactService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.MongoTransactionException;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@SpringBootTest
public class ContactServiceIntegrationTest {
@Autowired
ContactService contactService;
@Test
@Transactional
public void noDuplicateEmail() {
// given
ContactSaveRequestDto request = new ContactSaveRequestDto();
request.setEmail("email@domain.com");
// when
ContactDefaultResponseDto response = contactService.saveTest(request);
// then
Contact foundContact = contactService.findByEmail(response.getEmail());
assertThat(response.getEmail()).isEqualTo(foundContact.getEmail());
}
}

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
@Getter
@Document(collection = "contact")
@NoArgsConstructor
public class Contact {
@Id
private String id;
@NotBlank
@Indexed(unique = true)
private String email;
@NotBlank
private String verificationCode;
@NotBlank
private Boolean isVerified;
@NotBlank
private Boolean isRegistered;
@NotBlank
private LocalDateTime createdDate;
@NotBlank
private LocalDateTime modifiedDate;
@NotBlank
private String schemaVersion;
@Builder(builderClassName = "ByContactBuilder", builderMethodName = "ByContactBuilder")
public Contact(String email) {
this.email = email;
}
public void setVerificationCode(String verificationCode) {
this.verificationCode = verificationCode;
}
public void setIsVerified(Boolean isVerified) {
this.isVerified = isVerified;
}
public void setIsRegistered(Boolean isRegistered) {
this.isRegistered = isRegistered;
}
public void setCreatedDate(LocalDateTime createdDate) {
this.createdDate = createdDate;
}
public void setModifiedDate(LocalDateTime modifiedDate) {
this.modifiedDate = modifiedDate;
}
public void setSchemaVersion(String schemaVersion) {
this.schemaVersion = schemaVersion;
}
}

存储库

import com.inuappcenter.gabojaitspring.user.domain.Contact;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.Optional;
public interface ContactRepository extends MongoRepository<Contact, String> {
public Optional<Contact> findByEmail(String email);
}

服务

import com.inuappcenter.gabojaitspring.user.domain.Contact;
import com.inuappcenter.gabojaitspring.user.dto.ContactDefaultResponseDto;
import com.inuappcenter.gabojaitspring.user.dto.ContactSaveRequestDto;
import com.inuappcenter.gabojaitspring.user.repository.ContactRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
import java.util.Random;
@Service
@Slf4j
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ContactService {
private final ContactRepository contactRepository;
@Transactional
public ContactDefaultResponseDto saveTest(ContactSaveRequestDto request) {
Contact savedContact = contactRepository.save(request.toEntity());
savedContact.setVerificationCode(generateVerificationCode());
return new ContactDefaultResponseDto(savedContact);
}
private String generateVerificationCode() {
String chars = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz";
Random random = new Random();
random.setSeed(System.currentTimeMillis());
StringBuilder sb = new StringBuilder(6);
for (int i = 0; i < 6; i++)
sb.append(chars.charAt(random.nextInt(chars.length())));
return sb.toString();
}
public Contact findByEmail(String email) {
try {
Optional<Contact> contact = contactRepository.findByEmail(email);
if (contact.isEmpty()) {
log.error("");
throw new IllegalStateException();
} else {
return contact.get();
}
} catch (Exception e) {
log.error("", e);
throw new IllegalStateException();
}
}
}

MongoDB配置

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoTransactionManager;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.util.Collection;
import java.util.Collections;
@Configuration
@EnableMongoRepositories(basePackages = "com.inuappcenter.gabojaitspring")
public class MongodbConfiguration extends AbstractMongoClientConfiguration {
@Bean
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
return new MongoTransactionManager(dbFactory);
}
@Override
protected String getDatabaseName() {
return "gabojait";
}
@Override
public MongoClient mongoClient() {
final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/gabojait/?retryWrites=false");
final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
@Override
public Collection<String> getMappingBasePackages() {
return Collections.singleton("com.inuappcenter.gabojaitspring");
}
}

应用程序属性

spring.data.mongodb.authentication-database=admin
spring.data.mongodb.username=root
spring.data.mongodb.password=pass
spring.data.mongodb.database=gabojait
spring.data.mongodb.port=27017
spring.data.mongodb.host=localhost

原因

错误说明:

java.lang.IllegalArgumentException: state should be: databaseName does not contain '/'

是您的连接字符串无效。

求解

删除数据库名称后的斜杠。

更改连接字符串:

mongodb://localhost:27017/gabojait/?retryWrites=false

至:

mongodb://localhost:27017/gabojait?retryWrites=false

为什么会发生这种情况

数据库名称不应包含斜杠字符。

有效的数据库名称是非null、非空的,并且不包含以下任何字符:{@code'\0'、'/'、'\'、''、'"'、'.'}。服务器可能会对数据库名称施加其他限制
查看更多

当您将连接字符串传递给MongoDB驱动程序时,它会将字符串拆分为多个部分:

  • 主机:localhost
  • 端口:27017
  • 数据库:gabojait/
  • 选项:
    • retryWrites=false

驱动程序不会删除意外的尾部逗号。所以您得到了错误的数据库名称,看到验证器抛出的IllegalArgumentException

连接字符串的正确格式为:

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database.collection][?options]]

或者简单地针对单个主机:

mongodb://[username:password@]host[/[database][?options]]

最新更新