Spring EntityManager 不能扫描jar 中的class文件

项目中碰到一个问题,spring的entityManagerFactory,LocalEntityManagerFactoryBean 不能扫描在jar包中class(一个基础的,包含所有domain的工程,作为maven依赖导入)

需要自己实现一个FactoryBean来可以扫描jar包中的class(可以参考LocalEntityManagerFactoryBean的实现)

继承AbstractEntityManagerFactoryBean

public class ContainerEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean {

    private final DefaultPersistenceUnitManager persistenceUnitManager =
            new DefaultPersistenceUnitManager();

    private PersistenceUnitInfo           persistenceUnitInfo;
    private String[]                      packagesToScan;
    private String                        scanPackages = "";

 scanPackages 是新增属性,用来配置需要扫描的jar包

@Override
    protected EntityManagerFactory createNativeEntityManagerFactory() throws PersistenceException {
        PersistenceUnitManager managerToUse = this.persistenceUnitManager;
        this.persistenceUnitManager.setPackagesToScan(packagesToScan);
        this.persistenceUnitManager.afterPropertiesSet();
        managerToUse = this.persistenceUnitManager;

        this.persistenceUnitInfo = determinePersistenceUnitInfo(managerToUse);
        JpaVendorAdapter jpaVendorAdapter = getJpaVendorAdapter();
        if (jpaVendorAdapter != null && this.persistenceUnitInfo instanceof SmartPersistenceUnitInfo) {
            ((SmartPersistenceUnitInfo) this.persistenceUnitInfo).setPersistenceProviderPackageName(
                    jpaVendorAdapter.getPersistenceProviderRootPackage());
        }
        PersistenceProvider provider = getPersistenceProvider();
        if (logger.isInfoEnabled())
            logger.info("正在构建 JPA 容器 EntityManagerFactory, 持久化单元为:'" + this.persistenceUnitInfo.getPersistenceUnitName() + "'");

        scanEntitys();// 扫描实体并在创建实体工厂前添加到所使用的持久化单元里

        this.nativeEntityManagerFactory = provider.createContainerEntityManagerFactory(this.persistenceUnitInfo, getJpaPropertyMap());

        postProcessEntityManagerFactory(this.nativeEntityManagerFactory, this.persistenceUnitInfo);

        return this.nativeEntityManagerFactory;
    }

 基本拷贝了LocalEntityManagerFactoryBean中的,增加了scanEntitys()方法

private void scanEntitys() {
        String[] pgs = scanPackages.split(",");
        if (pgs.length > -1) {
            ClassPathScaner p = new ClassPathScaner();
            // p.addIncludeFilter(new AssignableTypeFilter(TypeFilter.class));
            // Set<MetadataReader> bd =
            // p.findCandidateClasss("org.springframework");
            p.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
            Set<MetadataReader> bd = p.findCandidateClasss(pgs);
            List<String> managedClass = persistenceUnitInfo.getManagedClassNames();
            for (MetadataReader b : bd) {
                if (!(managedClass.contains(b.getClassMetadata().getClassName()))) {
                    managedClass.add(b.getClassMetadata().getClassName());
                }
            }
        }
    }

 最后是在persistenceUnitInfo的manangedClass中增加

spring中的配置:

<bean id="entityManagerFactory"
		class="com.yto.zhiyun.scan.ContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="scanPackages" value="com.yto.zhiyun.common.entity" />
		<property name="packagesToScan" value="com.yto.zhiyun.entity" />
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
				p:database="${jpa.database}" p:showSql="${jpa.showSql}"
				p:databasePlatform="${jpa.databasePlatform}" />
		</property>
	</bean>

 

猜你喜欢

转载自patrick002.iteye.com/blog/2196020
今日推荐