如何过滤由LocalContainerEntityManagerFactoryBean扫描的实体? [英] How to filter entites scanned by LocalContainerEntityManagerFactoryBean?
问题描述
我使用Spring Boot,Spring Data JPA和Hibernate.
I use Spring Boot, Spring Data JPA and Hibernate.
我需要通过自定义注释过滤由EntityManager
管理的实体. LocalContainerEntityManagerFactoryBean
允许设置要扫描的软件包的列表,但过滤器似乎已在DefaultPersistenceUnitManager
中进行了硬编码.
I need to filter entities which are managed by EntityManager
by custom annotation. LocalContainerEntityManagerFactoryBean
allows to set a list of packages which are scanned but filters seems to be hardcoded in DefaultPersistenceUnitManager
.
否则,LocalSessionFactoryBuilder
(特定于休眠)具有此功能(方法setEntityTypeFilters
),但不能与需要EntityManagerFactory
的Spring Data JPA存储库一起使用.
Otherwise LocalSessionFactoryBuilder
(Hibernate specific) has this feature (method setEntityTypeFilters
) but can't be used with Spring Data JPA Repositories which require EntityManagerFactory
.
如何将实体过滤应用于LocalContainerEntityManagerFactoryBean
?
How can I apply entity filtering to LocalContainerEntityManagerFactoryBean
?
推荐答案
我有一个类似的问题:我想排除"某些实体,同时仍使用LocalContainerEntityManagerFactoryBean
提供的程序包扫描.就我而言,我想利用spring使用的@Profile(...)
注释,因为仅当特定配置文件处于活动状态时才需要某些实体.
我通过实现PersistenceUnitPostProcessor
来解决它,该PersistenceUnitPostProcessor
删除了扫描程序添加的类.它可能不是最优雅的解决方案,但它可以工作(春季4.1.2).
I had a similar problem: I want to "exclude" some Entities while still using package scanning provided by LocalContainerEntityManagerFactoryBean
. In my case, I wanted to make use of @Profile(...)
annotation used by spring since I need certain entities only if a specific profile is active.
I solved it by implementing a PersistenceUnitPostProcessor
which removes classes that were added by the scanner. It might not be the most elegant solution, but it works (Spring 4.1.2).
public class ProfileAwarePersistenceUnitPostProcessor implements PersistenceUnitPostProcessor {
@Autowired
Environment environment;
/**
* Post process the persistence unit and remove Entity classes that require a specific spring profile
* if profile is not active.
*
* @param pui The persistence unit that was put together so far.
* @see org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor#postProcessPersistenceUnitInfo(org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo)
*/
@Override
public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
// Check for null to be sure.
if (pui.getManagedClassNames() != null) {
Iterator<String> iterator = pui.getManagedClassNames().iterator();
while (iterator.hasNext()) {
String className = iterator.next();
try {
Class<?> entityClass = Class.forName(className);
Profile profileAnnotation = entityClass.getAnnotation(Profile.class);
if (profileAnnotation != null) {
String[] requiredProfiles = profileAnnotation.value();
if (!environment.acceptsProfiles(requiredProfiles)) {
Logging.debug("Removing class " + className + " from persistence unit since none of the required profiles is active "
+ StringUtils.join(", ", requiredProfiles));
iterator.remove();
}
}
} catch (ClassNotFoundException e) {
// Something must have gone wrong during scanning if class is suddenly not found anymore.
Logging.warn("Class " + className + " not found while post processing persistence unit.", e);
}
}
}
}
}
可以使用其他任何注释代替概要文件.
Any other annotation can be used instead of Profile.
这篇关于如何过滤由LocalContainerEntityManagerFactoryBean扫描的实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!