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