복붙노트

[SPRING] 사용자 정의 제약 검사기에서 Autowired Repository가 Null입니다.

SPRING

사용자 정의 제약 검사기에서 Autowired Repository가 Null입니다.

스프링 기반 웹 애플리케이션이 있습니다. 내 컨트롤러에서 @Repository, @Transactional 주석이있는 여러 저장소 클래스를 사용하고 있습니다. 그 부분은 잘 작동합니다.

저장소에 액세스해야하는 사용자 정의 제약 검사기를 만들었습니다. 이제 왜 저장소가 null인지 이해할 수 없습니다. @Component 주석을 사용하여 유효성 검사기에 주석을 달았습니다. 이러한 모든 클래스를 포함하는 기본 패키지는 xml에 포함되어 있습니다. 따라서 저장소 종속성 주입이 제대로 작동하도록하기 위해 무엇을해야합니까? 이것이 나의 Constraint 검사기의 모습입니다.

public class DonorTypeExistsConstraintValidator implements
    ConstraintValidator<DonorTypeExists, DonorType> {

  @Autowired
  private DonorTypeRepository donorTypeRepository;

  @Override
  public void initialize(DonorTypeExists constraint) {

  }

  public boolean isValid(DonorType target, ConstraintValidatorContext context) {

   System.out.println("donorType: " + target);
   if (target == null)
     return true;

   try {
    if (donorTypeRepository.isDonorTypeValid(target.getDonorType()))
     return true;
   } catch (Exception e) {
    e.printStackTrace();
   }
   return false;
  }

  public void setDonorRepository(DonorTypeRepository donorTypeRepository) {
    this.donorTypeRepository = donorTypeRepository;
  }
}

최신 정보

패키지 스캔 구성 :

<context:annotation-config />

<!-- Configures the @Controller programming model -->
<mvc:annotation-driven />

<context:component-scan base-package="controller" />
<context:component-scan base-package="repository" />
<context:component-scan base-package="model" />
<context:component-scan base-package="viewmodel" />

이 클래스는 model.donortype 패키지에 있습니다. 저장소가 패키지 저장소에 있습니다.

최신 정보

뭔가 더 수수께끼 같은, preinsert 리스너 (이 경우 BeanValidationEventListener 만)를 제거하면 autowiring 문제가 해결됩니다. 이것은 문제를 더욱 복잡하게 만든다.

아래 답변에 설명 된대로 BeanValidationEventListener를 삽입하지 않습니다. 이것은 여기에있는 제안과는 정반대입니다 : JSR-303 종속성 주입 및 최대 절전 모드

  @Override
  public void integrate(Configuration configuration, SessionFactoryImplementor implementor,
                        SessionFactoryServiceRegistry registry) {
      logger.info("Registering event listeners");
      System.out.println("here");
      // you can add duplication strategory for duplicate registrations

      final EventListenerRegistry eventRegistry = registry.getService(EventListenerRegistry.class);
      // prepend to register before or append to register after
      // this example will register a persist event listener

      eventRegistry.prependListeners(EventType.PERSIST, EntitySaveListener.class);
      eventRegistry.appendListeners(EventType.MERGE, EntitySaveListener.class);
      Iterator<PreInsertEventListener> iter = eventRegistry.getEventListenerGroup(EventType.PRE_INSERT).listeners().iterator();
      while (iter.hasNext()) {
        PreInsertEventListener el = iter.next();
        System.out.println(el.getClass());
        BeanValidationEventListener listener = (BeanValidationEventListener) el;
        System.out.println(listener);
        iter.remove();
      }
  }

최신 정보

JPA를 사용하고 있습니다. JPA 엔티티에 대한 백업 양식이 있습니다. 컨트롤러에서는 InitBinder를 사용하여 사용자 정의 유효성 검사기 binder.setValidator (new EntityBackingFormValidator (binder.getValidator ()));를 인스턴스화합니다. 이 코드는 다음과 같습니다. https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/controller/CollectedSampleController.java

이 사용자 지정 검사기는 기본 유효성 검사기에서 유효성 검사를 호출하고 일부 유효성 검사를 수행하도록 범위를 벗어납니다. https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/model/collectedsample/CollectedSampleBackingFormValidator.java

엔터티 내에서 주석을 사용하여 제약 조건을 만듭니다. 기본 제약과는 별도로, 다 대일 매핑의 반대편 엔티티가 존재하는지 여부를 확인하는 제약 조건을 정의해야합니다. 다음은 사용자 정의 제약 조건 유효성 검사기입니다. https://github.com/C4G/V2V/loblobe87

이제이 커스텀 제약 조건 검사기의 autowired 저장소가 null입니다. 여기에있는 내 CustomIntegrator에서 코드를 사용자 정의하려고합니다. https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/interceptor/CustomIntegrator.java

xml 구성 파일은 여기에 있습니다. https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/war/WEB-INF/v2v-servlet.xml

다행히도 실제 코드는 내 질문에 대한 답변을 제공합니다. 감사!

해결법

  1. ==============================

    1.어떤 ValidatorFactory를 사용하고 있습니까? 또는 다른 방법으로, 당신에게 뜨거운 콩 검증을 부트 스트랩? 디폴트로 Bean Validation (그리고 참조 implentation을위한 Hibernate Validator)은 ConstraintValidator 인스턴스에 의존성을 삽입하지 않는다. 적어도 Bean Validation 1.0.

    어떤 ValidatorFactory를 사용하고 있습니까? 또는 다른 방법으로, 당신에게 뜨거운 콩 검증을 부트 스트랩? 디폴트로 Bean Validation (그리고 참조 implentation을위한 Hibernate Validator)은 ConstraintValidator 인스턴스에 의존성을 삽입하지 않는다. 적어도 Bean Validation 1.0.

    종속성 삽입을 사용하려면 사용자 정의 ConstraintValidatorFactory를 구성해야합니다. Spring은 LocalValidatorFactoryBean을 사용할 때 기본값 인 SpringConstraintValidatorFactory를 제공합니다 - http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s07.html을 참조하십시오.

    또한 JPA를 사용하고 있습니까? 나는 그렇게 생각한다.이 경우 수명주기 이벤트에 대한 자동 검증이 자동으로 이루어진다. 이벤트 리스너를 제거하는 대신 javax.persistence.validation.mode 속성을 사용하고 NONE으로 설정할 수 있습니다. 올바른 유효성 검사기가 수명주기 기반 유효성 검사에 사용되는지 궁금합니다.

    그것은 모두 전체 Spring 설정과 사용에 달려 있습니다.

  2. ==============================

    2.유효성 검사를 수행 할 때 JPA에서 사용할 유효성 검사기 팩터 리를 전달합니까?

    유효성 검사를 수행 할 때 JPA에서 사용할 유효성 검사기 팩터 리를 전달합니까?

    <bean 
        id="entityManagerFactory" 
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="jpaPropertyMap">
            <map>
                <entry 
                    key="javax.persistence.validation.factory"
                    value-ref="validator"/>
                <!-- ... -->
            </map>
        </property>
        <!-- ... -->
    </bean>
    

    그렇지 않으면 기본 factory (validation.xml에 지정된대로)가 JPA에서 사용되기 때문에 필요합니다.

  3. ==============================

    3.DonorTypeExistsConstraintValidator에 @Component 주석이 있습니까?

    DonorTypeExistsConstraintValidator에 @Component 주석이 있습니까?

    그것은 과거에 나를 죽였다.

  4. ==============================

    4.LocalValidatorFactoryBean을 사용할 수 없습니다. 나는이 문제를 해결하기 위해 해킹을 해왔다.

    LocalValidatorFactoryBean을 사용할 수 없습니다. 나는이 문제를 해결하기 위해 해킹을 해왔다.

    @Component
    public class ServiceUtils
    {
        private static ServiceUtils instance;
    
        @Autowired
        private ListableBeanFactory factory;
    
        @PostConstruct
        public void init()
        {
            instance = this;
        }
    
        public static ListableBeanFactory getFactory()
        {
            return instance.factory;
        }
    }
    
  5. from https://stackoverflow.com/questions/13599821/autowired-repository-is-null-in-custom-constraint-validator by cc-by-sa and MIT license