многомодульный проект spring 3.0 Значение свойства AnnotationSessionFactoryBean packagesToScan должно быть установлено по модулю

У меня есть следующая структура:

общий модуль

  • Содержит общий модуль, связанный с сервисами и постоянством API.
  • Содержит общий контекст сохраняемости test-common-persistence-context.xml.

модуль поиска (зависит от общего модуля)

  • Содержит компоненты модели, связанные с модулем поиска (отмеченные аннотациями JPA Entity), сервисы и API сохранения.
  • Содержит связанные с поисковым модулем контекстные файлы spring.

booking-module (зависит от общего модуля) — содержит компоненты модели, связанные с модулем бронирования (отмеченные аннотациями JPA Entity), сервисы и API сохранения — содержит файлы контекста spring, связанные с модулем бронирования.

В общем модуле у меня есть test-common-persistence-context.xml. Для компонента sessionFactory, имеющего тип org.springframework.orm.hibernate3.annotation. AnnotationSessionFactoryBean Мне нужно установить значение свойства "packagesToScan" для пакетов, в которых присутствуют компоненты модели, отмеченные аннотацией JPA Entity. Без этого я получаю исключение Неизвестный объект: MY_ENTITY_NAME

Общий модуль: test-common-persistence-context.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:context="http://www.springframework.org/schema/context"
        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.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

            <!-- Property Place Holder -->
            <context:property-placeholder location="classpath:test-common-persistence-bundle.properties" />

            <!-- Data Source -->        
            <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                <property name="driverClassName" value="${test.db.driverClassName}"/>
                <property name="url" value="${test.db.jdbc.url}"/>
                <property name="username" value="${test.db.username}"/>
                <property name="password" value="${test.db.password}"/>
            </bean>

            <!--
                Hibernate Configuration
            --> 
            <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >
                <property name="dataSource" ref="dataSource"/>
                <property name="packagesToScan" value="${test.packages.to.scan.jpa.annotations}"/>
                <property name="hibernateProperties">
                    <value>
                        <!-- SQL dialect -->
                        hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
                        hibernate.hbm2ddl.auto=update
                    </value>
                </property>      
            </bean>

            <!-- Transaction Manager -->
            <bean id="txManager"  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
                <property name="sessionFactory" ref="sessionFactory"/>
            </bean>

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

    </beans>

В моем общем модуле нет объектов JPA, поэтому у меня нет пакетов для сканирования, поэтому я оставляю значение свойства "packagesToScan" пустым

Однако мне нужно использовать один и тот же контекст сохраняемости в моих тестах модуля поиска и модуля бронирования (SearchPersistenceTestBase.java), чтобы обнаруживались объекты JPA в соответствующем модуле.

Модуль поиска: SearchPersistenceTestBase.java

    @Ignore
    @ContextConfiguration(locations = {
            "classpath:test-common-persistence-context.xml",
            "classpath:test-search-spring-context.xml"})
    @TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
    public class SearchPersistenceTestBase extends AbstractTransactionalJUnit4SpringContextTests {

    }

Может ли кто-нибудь помочь мне в том, как добиться желаемого поведения с помощью настройки, которую я показал выше?

** Подход, который я пробовал **

Я подумал об использовании дополнительного bean-компонента типа java.lang.String, значение которого задается из файла свойств.

 <bean id="entityPackagesToScan" class="java.lang.String">
     <constructor-arg value="${test.packages.to.scan.jpa.annotations}" />
  </bean>

где test.packages.to.scan.jpa.annotations определяется как пустое в test-common-persistence-bundle.properties

Затем я переопределяю определение bean-компонента в test-search-spring-context.xml.

test-search-spring-context.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:context="http://www.springframework.org/schema/context"
    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.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

        <!-- Property Place Holder -->
        <context:property-placeholder location="classpath:test-search-bundle.properties" />

        .. context-component scan elements here

        <bean id="entityPackagesToScan" class="java.lang.String">
            <constructor-arg value="${test.packages.to.scan.jpa.annotations}" />
        </bean>
</beans>

где test.packages.to.scan.jpa.annotations определяется как «com.search.model» в test-search-bundle.properties.

Но это не сработало, и я получил исключение Неизвестный объект: MY_ENTITY_NAME

Спасибо,
Джинеш


person Jignesh Gohel    schedule 16.12.2011    source источник


Ответы (1)


Хорошо, я решил это. org.springframework.beans.factory.config.PropertyOverrideConfigurer — это то, что было нужно. Я размещаю здесь решение для справки на случай, если кто-то столкнется с похожей проблемой, о которой я упоминал в первом сообщении:

Общий модуль: test-common-persistence-context.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:context="http://www.springframework.org/schema/context"
        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.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

            <!-- Property Place Holder -->
            <context:property-placeholder location="classpath:test-common-persistence-bundle.properties" />

            <!-- Data Source -->        
            <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                <property name="driverClassName" value="${test.db.driverClassName}"/>
                <property name="url" value="${test.db.jdbc.url}"/>
                <property name="username" value="${test.db.username}"/>
                <property name="password" value="${test.db.password}"/>
            </bean>

            <!--
                Hibernate Configuration
            --> 
            <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >
                <property name="dataSource" ref="dataSource"/>
                <!-- Not setting "packagesToScan" property here.As common-module doesn't contain any JPA entities -->
                <property name="hibernateProperties">
                    <value>
                        <!-- SQL dialect -->
                        hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
                        hibernate.hbm2ddl.auto=update
                    </value>
                </property>      
            </bean>

            <!-- Transaction Manager -->
            <bean id="txManager"  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
                <property name="sessionFactory" ref="sessionFactory"/>
            </bean>

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

    </beans>

Модуль поиска: test-search-spring-context.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:context="http://www.springframework.org/schema/context"
       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.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

        .. context-component scan elements here

        <!-- 
        Holds the overridden value for the org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
        (id="sessionFactory" bean in test-common-persistence-context.xml (common module))
        "packagesToScan" property value set for search module.

        E.g. sessionFactory.packagesToScan=com.search.model.persistent 
        -->
    <context:property-override location="classpath:test-search-bundle.properties"/>
</beans>

Модуль поиска: test-search-bundle.properties

     ########### Packages to scan JPA annotation
     # This is used by org.springframework.beans.factory.config.PropertyOverrideConfigurer
     # to override   org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean's
     # packagesToScan property value which is different for each module i.e. 
     # common-module does not contain any persistent models
     # search-module and booking-module contains persistent models
     # which needs to be scanned by Spring container to detect them as JPA entities

     sessionFactory.packagesToScan=com.search.model.persistent

Спасибо,
Джинеш

person Jignesh Gohel    schedule 19.12.2011