java - 添加额外的包以使用 Spring 配置扫描到实体管理器?

标签 java spring jpa spring-batch entitymanager

我有一个 Spring Batch 应用程序,它有一个通常每个批处理作业都会引用的 Spring 上下文配置。这样每个批处理作业都使用相同的实体管理器。

批处理上下文.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”属性是否是在这种情况下采取的正确方法?有没有更好的方法来完成此行为?

编辑:

我能够使用 property-override 功能完成我需要的事情。下面是我使用的更新后的 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

有几种方法可以解决您的问题:

  1. 只需删除其中一个 bean - 将定义合并为一个。 我只是猜想这对你来说不是一个选择,否则你不会问。

  2. entityManagerFactory 定义为抽象的,然后您最终会得到一个 bean。

  3. 使用属性覆盖机制。这适合这样的场景,在这种情况下,您无法控制“顶级”bean,尽管您想要重新配置(从字面上覆盖其属性的值)在那里定义的 bean。

关于java - 添加额外的包以使用 Spring 配置扫描到实体管理器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14366558/

相关文章:

java - Android ListView 根据页脚大小将内容包装到一定大小

java - Eclipse RCP : Height of a search text in the toolbar in Eclipse 4. 6

java - 错误 java.lang.ClassNotFoundException : reactor. core.scheduler.TimedScheduler

java - JPA/hibernate : ManyToMany delete relation on Join Table

java - 限制映射以获得基于 JPA 的排序的特定一对一关系

java - JPA @ElementCollection @Enumerated 不插入

java - 如果我想使用 JUnit,是否禁止使用 AssertionErrors?

java - Spring Boot - 多部分文件最大上传大小异常

java - Spring 中有没有一种方法可以 Autowiring 给定类型的所有依赖项?

spring-test MockMvc kotlin DSL 缺乏异步支持?