本文介绍了如何过滤由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扫描的实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 00:36