从CommandLineRunner使用时,@ Aututired在ConstraintValidator中的存储库为null

时间:2017-11-30 14:35:24

标签: spring validation spring-boot

我尝试使用Spring Boot 1.5.9.RELEASE 设置Spring-Data-Rest应用程序。我有一个ConstraintValidator设置如下:

UniqueEmail.java

import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;
import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {UniqueEmailValidator.class})
@NotNull
@ReportAsSingleViolation
public @interface UniqueEmail {

    Class<?>[] groups() default {};

    String message() default "{eu.icarus.momca.backend.domain.validation.UniqueEmail.message}";

    Class<? extends Payload>[] payload() default {};

    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    static @interface List {
        UniqueEmail[] value();
    }

}

UniqueEmailValidator.java

import eu.icarus.momca.backend.domain.repository.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {

    @Autowired
    private AccountRepository accountRepository;

    @Override
    public void initialize(UniqueEmail annotation) {
    }

    @Override
    public boolean isValid(String email, ConstraintValidatorContext context) {
        return accountRepository.findByEmail(email) == null;
    }

}

我还为beforeCreatebeforeSave存储库方法设置了侦听器:

RestConfiguration.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@Configuration
public class RestConfiguration extends RepositoryRestConfigurerAdapter {

    @Override
    public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
        validatingListener.addValidator("beforeCreate", localValidatorFactoryBean());
        validatingListener.addValidator("beforeSave", localValidatorFactoryBean());
    }

    @Bean
    @Primary
    LocalValidatorFactoryBean localValidatorFactoryBean() {
        return new LocalValidatorFactoryBean();
    }

}

我的问题:

当通过REST端点调用存储库方法时,验证器似乎有效,但是我也尝试通过使用相同存储库的CommandLineRunner在连接的数据库中设置一些东西。验证对存储库的调用后,AccountRepository中的自动装配ConstraintValidatornull,即使它在CommandLineRunner中同时为空,也具有相同的空值InitAdminData.java存储库自动装配。我不明白这一点。

当从CommandLineRunner触发验证时,是否有人知道存储库为空的原因?

非常感谢任何帮助。 丹尼尔

编辑:添加了CommandLineRunner代码

import eu.icarus.momca.backend.domain.entity.Account; import eu.icarus.momca.backend.domain.entity.AccountDetails; import eu.icarus.momca.backend.domain.entity.AccountProfile; import eu.icarus.momca.backend.domain.entity.Client; import eu.icarus.momca.backend.domain.enumeration.AccountRoles; import eu.icarus.momca.backend.domain.enumeration.ClientRoles; import eu.icarus.momca.backend.domain.enumeration.GrantTypes; import eu.icarus.momca.backend.domain.repository.AccountRepository; import eu.icarus.momca.backend.domain.repository.ClientRepository; import eu.icarus.momca.backend.domain.service.AccountService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @Component public class InitAdminData implements CommandLineRunner { private static final Collection<AccountRoles> DEFAULT_ACCOUNT_ROLES = Arrays.asList(AccountRoles.ROLE_ACCOUNT, AccountRoles.ROLE_ADMINISTRATOR, AccountRoles.ROLE_CLIENT_OWNER); private static final Logger logger = LoggerFactory.getLogger(InitAdminData.class); private AccountRepository accountRepository; private AccountService accountService; @Value("${app.admin-email}") private String adminEmail; @Value("${app.admin-name}") private String adminName; @Value("${app.admin-password}") private String adminPassword; private ClientRepository clientRepository; @Value("${app.default-client-description}") private String defaultClientDescription; @Autowired public InitAdminData(AccountRepository accountRepository, AccountService accountService, ClientRepository clientRepository) { this.accountRepository = accountRepository; this.clientRepository = clientRepository; this.accountService = accountService; } private Account initAdminAccount() { Account adminAccount = accountRepository.findByAccountProfile_Name(adminName); if (adminAccount == null) { adminAccount = new Account(); logger.info("Initialized new admin account"); } else { logger.info("Refreshed admin account"); } setAdminAccountData(adminAccount); return accountService.save(adminAccount, adminPassword); } private void initDefaultClient(Account adminAccount) { long adminAccountId = adminAccount.getId(); Collection<Client> adminClients = clientRepository.findAllByOwnerId(adminAccountId); if (adminClients.isEmpty()) { Client defaultClient = new Client(); defaultClient.setOwnerId(adminAccountId); defaultClient.setDescription(defaultClientDescription); Collection<ClientRoles> clientRoles = new HashSet<>(2); clientRoles.add(ClientRoles.ROLE_CLIENT); clientRoles.add(ClientRoles.ROLE_DEFAULT_CLIENT); defaultClient.setRoles(clientRoles); Collection<GrantTypes> grantTypes = new HashSet<>(); grantTypes.add(GrantTypes.authorization_code); grantTypes.add(GrantTypes.client_credentials); grantTypes.add(GrantTypes.password); grantTypes.add(GrantTypes.refresh_token); defaultClient.setGrantTypes(grantTypes); defaultClient = clientRepository.save(defaultClient); logger.info(String.format("Added new default client with id '%s'", defaultClient.getId())); } } @Override public void run(String... args) { Account adminAccount = initAdminAccount(); initDefaultClient(adminAccount); } private void setAdminAccountData(Account adminAccount) { adminAccount.setEmail(adminEmail); adminAccount.setRoles(DEFAULT_ACCOUNT_ROLES); adminAccount.setAccountDetails(new AccountDetails()); adminAccount.setAccountProfile(new AccountProfile(adminName)); } }

HKH = {}
with open("myfile","r") as file:
    for line in file:
        try:
            GID, CRR = line.strip().split()
        except ValueError:
            continue
        else:
            HKG[GID] = CRR

2 个答案:

答案 0 :(得分:0)

添加@ComponentScan注释。

@ComponentScan
public class InitAdminData implements CommandLineRunner {
 ...
}

答案 1 :(得分:0)

我认为你的病例很少: -

  1. 您尚未自动提供服务和Repo
  2. 您没有在您的服务和回购地点扫描您的回购。
  3. 或者您没有在自动装配的类上使用@Component(任何构造型)注释