java - 如何过滤 LocalContainerEntityManagerFactoryBean 扫描的实体?

标签 java spring jpa spring-data spring-data-jpa

我使用 Spring Boot、Spring Data JPA 和 Hibernate。

我需要通过自定义注释过滤由 EntityManager 管理的实体。 LocalContainerEntityManagerFactoryBean 允许设置扫描的包列表,但过滤器似乎在 DefaultPersistenceUnitManager 中硬编码。

否则 LocalSessionFactoryBuilder(特定于 Hibernate)具有此功能(方法 setEntityTypeFilters)但不能与需要 EntityManagerFactory 的 Spring Data JPA 存储库一起使用>.

如何将实体过滤应用于 LocalContainerEntityManagerFactoryBean

最佳答案

我有一个类似的问题:我想“排除”一些实体,同时仍然使用 LocalContainerEntityManagerFactoryBean 提供的包扫描。就我而言,我想利用 spring 使用的 @Profile(...) 注释,因为仅当特定配置文件处于 Activity 状态时我才需要某些实体。 我通过实现 PersistenceUnitPostProcessor 解决了这个问题,它删除了扫描器添加的类。它可能不是最优雅的解决方案,但它有效(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);
                }
            }
        }
    }
}

可以使用任何其他注释来代替配置文件。

关于java - 如何过滤 LocalContainerEntityManagerFactoryBean 扫描的实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31604487/

相关文章:

java - 如何设置 Swing 计时器在启动时执行

java - 我正在使用 bean 验证。在我的实体的 PerPersist 方法中,如果验证失败,如何停止持久化?

java - 在 netbeans 中从数据库创建实体类时如何过滤表?

java - 使用 JPA Hibernate 创建 MySQL 存储过程

java - 如何根据另一个组合框中的选择禁用组合框?

java - Gradle在相关测试项目中找不到包

java 插入 null 但不插入原始默认值

java - BindingResult 未检测到 JSR :303 annotation based errors

java - Spring MVC注解配置问题

spring - 如何在 Spring 中以编程方式获取 entitymanager?