6

Spring ベースの webapp があります。コントローラーで注釈 @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 にあります。リポジトリはパッケージ リポジトリにあります。

アップデート

さらに不可解なことに、すべての事前挿入リスナー (この場合は BeanValidationEventListener のみ) を削除すると、自動配線の問題が修正されます。これは問題をさらに複雑にしました。

以下の回答で説明されているように、BeanValidationEventListener を挿入することさえしていません。これは、 JSR-303 依存性注入と Hibernateの提案に反する事実です。

  @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/model/collectedsample/CollectedSampleBackingFormValidator.java

エンティティ内で注釈を使用して制約を作成しています。デフォルトの制約とは別に、多対 1 マッピングの反対側にエンティティが存在するかどうかをチェックする制約を定義する必要があります。これがカスタム制約バリデータです。 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/model/donor/DonorExistsConstraintValidator.java

現在、このカスタム制約バリデーターの自動接続されたリポジトリーは 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

実際のコードが私の質問に答えるのに役立つことを願っています。ありがとう!

4

4 に答える 4

15

どのValidatorFactoryを使用していますか。または、別の言い方をすれば、ブートストラップ Bean Validation に興味がありますか? デフォルトでは、Bean Validation (および参照実装としての 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 の全体的な構成と使用に依存します。

于 2012-11-29T07:35:19.637 に答える
3

検証を実行するときに 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>

そうしないと、デフォルトのファクトリ ( validation.xmlで指定) が JPA によって使用されるため、これが必要です。

于 2012-12-08T16:46:38.250 に答える
0

DonorTypeExistsConstraintValidatorに@Componentアノテーションがありますか?

それは過去に私を殺しました。

于 2012-12-07T22:24:26.273 に答える