0

I have implemented a PersistenceUnitPostProcessor for scanning the entities in different packages and not listing them in the persistence.xml.

Sadly, it is only working during deployment but not when running junit tests.

The Processor is declared in the context application xml as follow:

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

The packages are listed as:

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

The logic:

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);
        }
      }
    }

The Test definition:

@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 {
}

The super class:

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

}

I'm getting this exception:

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

What can be the issue, that the Processor works during deplyoment but not druing unit testing? Am I overseeing something?

Any hint is very welcome.

4

1 に答える 1

0

そんなお悩みをお持ちの方へ。

エラーの理由は次の式でした。

"classpath:%s/*.class"

次のように変更します。

"classpath*:%s/*.class"

エラーを解決しました。

問題は、最初の式が見つかった最初のパスだけを参照することでした。この場合、そのようなエラー メッセージの原因となっているエンティティのように、必要なクラスが存在しません。

2 番目の式は、パス パターンに一致するすべてのクラス ディレクトリを検索するように ResourcePatternResolver に指示します。

../classes/package1/Entity.class

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

私の場合、以前は次のことだけを探していました。

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

これが誰かに役立つことを願っています。

于 2015-01-22T09:06:48.823 に答える