项目中碰到一个问题,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>