我有一个
Spring Batch应用程序,它有一个Spring上下文配置,通常每个批处理作业都会引用它.这样,每个批处理作业使用相同的实体管理器.
批量context.xml中:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- ... -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="myPersistenceUnit" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="packagesToScan" value="com.example.domain" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">100</prop>
<prop key="hibernate.jbc.batch_size">1000</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.use_sql_comments">false</prop>
</props>
</property>
</bean>
<!-- ... -->
</beans>
现在在我的特定批处理作业上下文(称为ExampleBatch.xml)中,我想添加另一个包以扫描到已定义的entityManagerFactory bean.这可能吗?
ExampleBatch.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd">
<!-- ... -->
<import resource="classpath:batch-context.xml" />
<bean id="entityManagerFactoryWithExtraPackages"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
parent="entityManagerFactory">
<!-- How do I override the packagesToScan property on the already defined entityManagerFactory bean?-->
<property
name="packagesToScan"
value ="com.example.domain,com.example.domain.abstraction"
/>
</bean>
<!-- ... -->
</beans>
我现在拥有它的方式将无法工作,因为它抱怨“没有定义[javax.persistence.EntityManagerFactory]类型的唯一bean:期望的单个bean但找到2”
是否试图在这种情况下覆盖“packagesToScan”属性的正确方法?有没有更好的方法来实现这种行为?
编辑:
我能够使用属性覆盖功能完成我需要的工作.下面是我使用的更新的ExampleBatch.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd">
<!-- ... -->
<import resource="classpath:batch-context.xml" />
<context:property-override properties-ref="entityManagerOverride"/>
<bean id="entityManagerOverride"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<util:properties>
<prop key="entityManagerFactory.packagesToScan">com.example.domain,com.example.batch.module.domain</prop>
</util:properties>
</property>
</bean>
<!-- ... -->
</beans>
到目前为止,Spring并没有对我大喊大叫,这是一个无效的配置.尚未确定这是否实际上产生了预期的结果.
编辑2:
属性覆盖方法似乎不够.它是一个有效的配置,但在运行时检查实体管理器后,如下所示:
for (EntityType<?> entity : manager.getMetamodel().getEntities()) {
String name = entity.getName();
System.out.println(name);
}
它只包含com.example.domain包中的实体.
有没有人有任何其他想法?
最佳答案 你现在拥有它的方式,你真的定义了两个独立的bean – 一个叫做entityManagerFactory,另一个是entityManagerFactoryWithExtraPackages.
有几种方法可以解决您的要求:
>只需摆脱其中一个bean – 将定义合并为一个.
我只是觉得这不是你的选择,否则你不会问.
>将entityManagerFactory定义为abstract,然后最终得到一个bean.
>使用属性覆盖机制.这适用于您无法控制’top’bean的场景,尽管您想要重新配置(字面上覆盖其中定义的属性的值)bean.