1

Hibernate DAOとモデルオブジェクトレイヤーを既存のアプリケーションから分割して、複数のアプリケーションで使用できるようにしようとしています。残念ながら、私はあまり成功していません。アプリケーションコンテキストからSessionFactoryを取得しようとすると、NoSuchBeanDefinitionExceptionがスローされます。

すべてのDAOクラスは、GenericDaoHibernate2と呼ばれるクラスを拡張します。各DAOはこれを拡張し、コンストラクターでクラスを渡します。かなり標準的な汎用DAOのもの。

これがセッションファクトリを設定するための論理的な場所になると思いました(DAOクラスはたくさんあります)。したがって、コンストラクタークラスでは、次のようにしました。

public GenericDaoHibernate2(final Class<T> persistentClass) {
    ctx = new ClassPathXmlApplicationContext("META-INF/applicationContext-dao.xml");
    this.sessionFactory = (SessionFactory) ctx.getBean(SessionFactory.class);
    log.debug("Value of app context: " + ctx.toString());
    log.debug("Value of sessionFactory: " + sessionFactory);
    this.persistentClass = persistentClass;
}

残念ながら、これは前述の例外で爆発しました:

Caused By: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:551)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
Truncated. see log file for complete stacktrace

また、クラスパス内のアプリコンテキストファイルを使用してこれを試み、変数を宣言するときに値を設定するなどしました。

何が起こっているのかは、 Mavenビルドの一部として、jarがクラスパス上のライブラリを参照していないことだと思いますが、実際にはわかりません...

更新:愚かな、愚かな私...アプリケーションコンテキストファイルを表示するのを忘れました。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/jee
       http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"
    default-lazy-init="true">

    <tx:annotation-driven transaction-manager="transactionManager" />
    <context:component-scan base-package="org.jason.dao.hibernate" />


    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@//192.168.1.1/db01" />
        <property name="username" value="USER" />
        <property name="password" value="PASSWORD" />
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibername.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.jdbc.use_get_generated_keys">true</prop>
                <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
                <prop key="hibernate.default_catalog">CATALOG</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
                </prop>
            </props>
        </property>
        <property name="packagesToScan">
            <list>
                <value>org.jason.model</value>
            </list>
        </property>
    </bean>
</beans>

別の更新:サンプルDAOを求められました。このインターフェースは「標準」のジェネリックインターフェースであり、Implと同様に、ジェネリックパラメーターTおよびPKを受け入れます。次のメソッドには、GenericDaoHibernate2から継承するもの以外の特定のメソッドはありません。

@Repository("AreaOfPreferenceDAO")
public class HibernateAreaOfPreferenceDAO extends GenericDaoHibernate2<AreaOfPreference, AreaOfPreferenceCompositeId> implements AreaOfPreferenceDAO {

   public HibernateAreaOfPreferenceDAO()
   {
      super(AreaOfPreference.class);
   }
}
4

3 に答える 3

1

SessionFactoryをカスタムの汎用DAOに接続するには、Springコンテキスト全体がSessionFactory Beanを定義している限り、先に進んで@Autowireを使用するだけです。Beanを定義するには:

<bean id="sessionFactory" class=
    "org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
   <property name="dataSource" ref="dataSource" />
   <property name="packagesToScan" value="org.rest" />

   <property name="hibernateProperties">
      ...
   </property>
</bean>
<bean id="dataSource" class=
    "org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName" value="${driverClassName}" />
   <property name="url" value="${url}" />
   <property name="username" value="restUser" />
   <property name="password" value="restmy5ql" />
</bean>

そして、配線するには、単純に:

@Autowired
SessionFactory sessionFactory;

コンテキストをブートストラップする適切な場所は、DAOのコンストラクターではありません。Webアプリケーションを使用している場合は、従来のアプローチを使用できます。

<servlet>
   <servlet-name>dispatcher</servlet-name>
   <servlet-class>
     org.springframework.web.servlet.DispatcherServlet
   </servlet-class>
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
   <servlet-name>dispatcher</servlet-name>
   <url-pattern>/</url-pattern>
 </servlet-mapping>

これはWebアプリケーションではないため、コンテキストをweb.xmlでブートストラップすることはできません。ただし、ブートストラップは引き続き外部である必要があります。メインクラスは、XmlWebApplicationContextを作成して構成するだけです。

お役に立てれば。

于 2012-08-20T12:51:38.737 に答える
1

各DAOオブジェクトで新しいアプリケーションコンテキストを作成しているという事実は、問題を引き起こしている可能性があります。

ctx = new ClassPathXmlApplicationContext("META-INF/applicationContext-dao.xml");

考えてみれば、これは一種の循環です。DAOのコンポーネントスキャンを実行するコンテキストを呼び出すと、DAOはDAOのコンポーネントスキャンを実行する新しいコンテキストをインスタンス化します...

他の誰かが言ったように、私はセッションファクトリーを直接自動配線します。

@Repository("AreaOfPreferenceDAO")
public class HibernateAreaOfPreferenceDAO extends GenericDaoHibernate2<AreaOfPreference, AreaOfPreferenceCompositeId> implements AreaOfPreferenceDAO {

   @Autowired
   public HibernateAreaOfPreferenceDAO(SessionFactory sessionFactory)
   {
      super(sessionFactory, AreaOfPreference.class);
   }
}

コンポーネントは、新しいアプリケーションコンテキストを構築する必要はありません。

于 2012-08-20T13:12:50.817 に答える
0

同じ問題があり、注射を機能させることができませんでした。

私の問題は「シーケンス」でした。Hibernatexmlを最初に呼び出す必要があります。

dispatcher-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

<!-- init hibernate first -->
<import resource="classpath:HibernateContext.xml"/>

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="suffix" value=".jsp" />
</bean>
<mvc:annotation-driven />
<context:component-scan base-package="com.xxx.yyy" />

hibernateContext.xmlのコンテンツ:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

<bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:database.properties</value>
        </list>
    </property>
</bean>

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driver}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.user}" />
    <property name="password" value="${jdbc.password}" />
</bean>

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.xxx.yyy.model" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>

    </property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<!--  bean id="transactionManager" class=" org.springframework.transaction.jta.JtaTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean-->

于 2013-06-13T18:19:14.277 に答える