You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中MongoRepository初始化失败及自定义Repository依赖缺失问题

问题:Spring Data MongoDB Repository 查询生成失败及自定义Repository Bean找不到

我搜了大量相关问答,但每个场景都不一样,折腾一小时没找到解决方案,求指引。

初始错误信息

报错核心是org.springframework.beans.factory.UnsatisfiedDependencyException:创建appUserService Bean时,构造参数0依赖的appUserRepository初始化失败。嵌套异常显示Spring Data无法为AppUserRepository的enableAppUser方法生成查询,提示AppUser类中没有enableAppUser属性。完整错误栈:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'appUserService' defined in file [D:\portfolio\TripAdvisorApp\target\classes\demo\tripadvisorapp\security\appuser\AppUserService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appUserRepository' defined in demo.tripadvisorapp.security.appuser.AppUserRepository defined in @EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract int demo.tripadvisorapp.security.appuser.AppUserRepository.enableAppUser(java.lang.String); Reason: No property 'enableAppUser' found for type 'AppUser'; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property 'enableAppUser' found for type 'AppUser'
...(省略后续栈信息)

相关代码

AppUserService

@Service
@AllArgsConstructor
public class AppUserService implements UserDetailsService {
    private final static String USER_NOT_FOUND_MESSAGE = "User with email %s not found";
    private final AppUserRepository appUserRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    private final ConfirmationTokenService confirmationTokenService;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        return appUserRepository.findByEmail(email).orElseThrow(() ->
                new UsernameNotFoundException(String.format(USER_NOT_FOUND_MESSAGE, email)));
    }

    public String signUpUser(AppUser appUser) {
        boolean userExists = appUserRepository.findByEmail(appUser.getEmail())
                .isPresent();
        if (userExists) {
            throw new IllegalStateException("Email already taken");
        }
        String encodedPassword = bCryptPasswordEncoder.encode(appUser.getPassword());

        appUser.setPassword(encodedPassword);

        appUserRepository.save(appUser);

        String token = UUID.randomUUID().toString();
        ConfirmationToken confirmationToken = new ConfirmationToken(
                token,
                LocalDateTime.now(),
                LocalDateTime.now().plusMinutes(15),
                appUser
        );

        confirmationTokenService.saveConfirmationToken(confirmationToken);

        return token;
    }

    public int enableAppUser(String email) {
        return appUserRepository.enableAppUser(email);
    }
}

AppUserRepository

@Transactional(readOnly = true)
@Repository
public interface AppUserRepository extends MongoRepository<AppUser, Long> {

    Optional<AppUser> findByEmail(String email);

    @Transactional
    int enableAppUser(String email);
}

AppUser

@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@Document("app_user")
public class AppUser implements UserDetails {

        @Id
        private String id;
        private String firstName;
        private String lastName;
        private String email;
        private String password;
        private AppUserRole appUserRole;
        private Boolean locked = false;
        private Boolean enabled = false;
    
        public AppUser(String firstName,
                       String lastName,
                       String email,
                       String password,
                       AppUserRole appUserRole) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.email = email;
            this.password = password;
            this.appUserRole = appUserRole;
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(appUserRole.name());
            return Collections.singletonList(authority);
        }
    
        @Override
        public String getPassword() {
            return password;
        }
    
        @Override
        public String getUsername() {
            return email;
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return !locked;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return enabled;
        }
    }

尝试解决及新问题

  1. 尝试添加@ComponentScan注解:
@ComponentScan(basePackages = {"demo.tripadvisorapp.security.token"})
@ComponentScan(basePackages = {"demo.tripadvisorapp.security.appuser"})

但问题未解决。

  1. 按照建议创建自定义Repository后,出现新错误:
Parameter 1 of constructor in demo.tripadvisorapp.security.appuser.impl.AppUserServiceImpl required a bean of type 'demo.tripadvisorapp.security.token.CustomizedUserRepository' that could not be found.

Action:

Consider defining a bean of type 'demo.tripadvisorapp.security.token.CustomizedUserRepository' in your configuration

解决方案指引

针对第一个错误(查询生成失败)

Spring Data MongoDB的方法命名规则基于实体属性,enableAppUser不符合规则——实体里只有enabled属性。可以用两种方式修正:

  • 方法命名规范修正:
    改成符合更新操作的命名,让Spring自动生成查询:
    @Transactional
    int updateEnabledByEmail(boolean enabled, String email);
    
    调用时传入true和目标邮箱即可。
  • 手动指定查询语句:
    用@Query注解直接写MongoDB更新语句:
    @Transactional
    @Query(value = "{'email': ?0}", update = "{$set: {'enabled': true}}")
    int enableAppUser(String email);
    

针对第二个错误(自定义Repository Bean找不到)

  • 检查@EnableMongoRepositories的basePackages是否包含自定义Repository所在的demo.tripadvisorapp.security.token包,确保Spring能扫描到该接口。
  • 若自定义Repository是「接口+实现类」模式:
    • 实现类默认命名规则为「接口名+Impl」,比如CustomizedUserRepositoryImpl,否则需要在接口上用@RepositoryDefinition指定实现类。
    • 实现类要加@Repository或@Component注解,让Spring将其纳入Bean管理。
  • 检查AppUserServiceImpl的构造参数注入是否正确,确保依赖的CustomizedUserRepository是Spring管理的合法Bean。

内容的提问来源于stack exchange,提问作者Stefan Jankovic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:45:36