0

私は現在、Hibernateを統合したSpringMVCプロジェクトに取り組んでいます。純粋なSpringMVC部分(DispatcherServlet +リクエストマッピング)は正常に機能します。さて、私が対処しなければならない問題は非常に奇妙です。「Java Persistence with Hibernate」を読み、本で説明されているのと同様の方法で永続性レイヤーを設計しようとしています。つまり、2つの並列階層で設計しました。1つは実装クラス用で、もう1つはインターフェイス用です。

したがって、GenericDaoインターフェイスを実装するGenericDaoImplという名前の抽象クラスがあります。次に、GenericDaoImplを拡張し、AdvertisementDaoインターフェイス(GenericDaoを拡張)を実装するAdvertisementDaoImplという名前の具象クラスがあります。

次に、サービスBean(@Serviceでマークされたクラス)で、daoクラスを自動配線します。

これが私の問題です:

  • インターフェイスを実装するが、抽象GenericDaoImplクラスを拡張しないDAOクラスの自動配線:OK
  • AdvertisementDaoインターフェースを実装し、抽象GenericDaoImplクラスを拡張するAdvertisementDaoImplを自動配線すると、Bean初期化例外が発生します。

DAO階層の最上位にある抽象クラスは、一般的なCRUDメソッドのすべての定型コードを処理します。だから、絶対に残したいです。

誰かがそれについて説明がありますか?

これがコードの抜粋です:

public abstract class GenericDaoImpl <T, ID extends Serializable> implements BeanPostProcessor, GenericDao<T, ID>{
    @Autowired(required=true)
    private SessionFactory sessionFactory;
    private Session currentSession;
    private Class<T> persistentClass;

...
}


@Repository
public class AdvertisementDaoImpl extends GenericDaoImpl<Advertisement, Long> implements AdvertisementDao {

...


    public List<Advertisement> listAdvertisementByType(AdvertisementType advertisementType, Class<? extends Good> type) {
        return null;
    }

}

@Service
public class AdvertisementServiceImpl implements AdvertisementService{
    @Autowired(required=false)
    private AdvertisementDao advertisementDao;

    public List<Advertisement> listAllAdvertisements() {

        return null;
    }

}

スタックトレースの最も関連性の高い部分は次のとおりです(少なくとも、そうだと思います)。

ネストされた例外はorg.springframework.beans.factory.BeanCreationExceptionです:フィールドを自動配線できませんでした:be.glimmo.service.AdvertisementService be.glimmo.controller.HomeController.advertisementService; ネストされた例外はjava.lang.IllegalArgumentExceptionです:be.glimmo.service.AdvertisementServiceフィールドbe.glimmo.controller.HomeController.advertisementServiceをbe.glimmo.dao.AdvertisementDaoImplに設定できません

そしてこれが私のSpring設定です(pastebin.comへのリンク):

4

2 に答える 2

0

proxy-target-classトランザクション管理構成で使用する必要があると思います。

<tx:annotation-driven transaction-manager="transactionManagerForHibernate" 
     proxy-target-class="true" />

あなたが説明する問題の症状は、Spring Transaction Management(表10.2を参照)およびSpringを使用したAOPプロキシで言及されているものと一致します。

プロキシされるターゲットオブジェクトが少なくとも1つのインターフェイスを実装している場合、JDK動的プロキシが使用されます。ターゲットタイプによって実装されるすべてのインターフェイスがプロキシされます。ターゲットオブジェクトがインターフェイスを実装していない場合は、CGLIBプロキシが作成されます。

したがって、デフォルトでCGLIBがない場合、実装されたインターフェイスからのすべてのメソッドがありますが、階層内のスーパークラスからのメソッドのプロキシが失われるため、例外が発生します。

于 2012-05-27T10:27:21.773 に答える
0

さらにいくつかのテストを行った結果、BeanPostProcessorインターフェースを実装する抽象GenericDaoImplクラスが問題の原因であることが判明しました。何らかの理由で、このインターフェースのメソッドは、このBeanのインスタンス化だけでなく、すべてのBeanのインスタンス化でも実行されました。

BeanPostProcessorフックメソッド内でジェネリックスのパラメーター化された型を取得していた場合、これらのメソッドがDAO階層にないクラスに対して実行されると、実行時例外(より具体的には、ClassCastException)が発生します。

そのため、この問題を解決するために、GenericDaoImplクラスでBeanPostProcessorインターフェイスを実装しなくなり、フックメソッドの本体を空のコンストラクターに移動しました。

于 2012-05-28T12:56:26.250 に答える