0

我已经实现了一个 PersistenceUnitPostProcessor 来扫描不同包中的实体,而不是在 persistence.xml 中列出它们。

可悲的是,它仅在部署期间有效,但在运行 junit 测试时无效。

处理器在上下文应用程序 xml 中声明如下:

<bean id="entityManagerFactoryMdm"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitPostProcessors">
        <list>
            <bean class="com.mypackage.MyPersistenceUnitPostProcessor" />
        </list>
    </property>
</bean>

软件包列表如下:

<util:properties id="entitiesScanProperties">
    <prop key="packagesToScan">package1.entities,package2.entities.view,package3.entities</prop>
</util:properties>

逻辑:

public class MyPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor {

    @Autowired
    private ResourcePatternResolver resourceLoader;

    @Value("#{entitiesScanProperties['packagesToScan']}")
    private String[] packagesToScan;

    @Override
    public void postProcessPersistenceUnitInfo(final MutablePersistenceUnitInfo mutablePersistenceUnitInfo) {
        try {
            List<Resource> resourcesList = new ArrayList<Resource>();
            for (String packageToScan : packagesToScan) {
                packageToScan = packageToScan.replace(".", "/");
                final Resource[] packageResources = resourceLoader.getResources(String.format("classpath:%s/*.class", packageToScan));
                resourcesList.addAll(Arrays.asList(packageResources));
            }
            final Resource[] resources = new Resource[resourcesList.size()];
            resourcesList.toArray(resources);

            for (Resource resource : resources) {
                final CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
                final MetadataReader metadataReader = cachingMetadataReaderFactory.getMetadataReader(resource);
                if (metadataReader.getAnnotationMetadata().isAnnotated(javax.persistence.Entity.class.getName())) {
                    mutablePersistenceUnitInfo.addManagedClassName(metadataReader.getClassMetadata().getClassName());
                }
            }
            mutablePersistenceUnitInfo.setExcludeUnlistedClasses(true);
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
      }
    }

测试定义:

@ContextConfiguration(locations = { "classpath:application-context-test.xml" })
@DatabaseDataAsResource(locations = { "/META-INF/testdata/dbunit/master-dataset.xml", "/META-INF/testdata/dbunit/complaints-dataset.xml" })
public class FuelComplaintServiceImplIntegrationTest extends TestBase {
}

超级班:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class, TestExecutionLifecycleListener.class })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public abstract class TestBase {

}

我得到了这个例外:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private     com.company.repository.DataProviderRepository com.company.service.impl.ProviderConfigurationServiceImpl.dataProviderRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataProviderRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Not an managed type: class package1.entities.DataProviderEntity
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 43 more

处理器在部署期间工作但在单元测试期间不工作可能是什么问题?我在监督什么吗?

任何提示都非常受欢迎。

4

1 回答 1

0

对于那些可能遇到此类问题的人。

错误的原因是这个表达式:

"classpath:%s/*.class"

将其更改为:

"classpath*:%s/*.class"

解决了错误。

问题是,第一个表达式只会在找到的第一个路径中查找。一些需要的类不会像在这种情况下那样存在导致此类错误消息的实体。

第二个表达式将告诉 ResourcePatternResolver 查看与路径模式匹配的所有类目录,例如

../classes/package1/Entity.class

../test-classes/package1/ServiceTest.class

就我而言,它以前只是为了:

../test-classes/package1/ServiceTest.class

希望这可以帮助某人。

于 2015-01-22T09:06:48.823 回答