Spring Boot 2 MultiProject Build忽略子项目中的application.yml

时间:2019-05-17 14:56:01

标签: java spring-boot spring-data-jpa

我正在使用Spring Boot 2.1.5.RELEASE进行多项目构建。

我在https://github.com/MBurchard/ACME上分享了一个示例

从存储子项目运行测试用例时,将找到并使用存储项目内部的所有YAML配置。

使用配置文件dev从Web项目运行SpringBootApplication时,显示错误。

spring:
  # PROFILES
  profiles:
    active: ${profile:dev}

错误原因

Caused by: java.lang.IllegalArgumentException: Not a managed type: class de.mbur.acme.User
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:552) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:74) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]

原因很明显。它不使用存储项目中的application.yml。

切换到dev-full-config时,一切都可以正常工作

spring:
  # PROFILES
  profiles:
    active: ${profile:dev-full-config}

但是我不想为或多或少内部的数据库重复完整的配置。

在不重复内部数据库配置的情况下该如何做?

1 个答案:

答案 0 :(得分:0)

我通过编写增强的存储配置来解决此问题,该配置可以查找和使用Hibernate映射文件,而且可以在测试或运行时尊重属性的外部配置...

有关详细信息,请访问:https://github.com/MBurchard/ACME/commit/499dbb128efb08614145754dc54e2ae8d4fc5d00

package de.mbur.acme.storage;

import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.sql.DataSource;

import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.slf4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import static org.slf4j.LoggerFactory.getLogger;

@Configuration
class MySQLConfig {
    private static final Map<String, String> HIBERNATE_MAPPINGS = Stream.of(new String[][]{
            {"hibernate.format_sql", "spring.jpa.properties.hibernate.format_sql"},
            {"hibernate.show_sql", "spring.jpa.show-sql"},
    }).collect(Collectors.collectingAndThen(
            Collectors.toMap(data -> data[0], data -> data[1]),
            Collections::<String, String>unmodifiableMap));
    private static final Logger LOG = getLogger(MySQLConfig.class);

    static {
        LOG.debug("Hier bin ich");
    }

    private final Environment env;

    MySQLConfig(final Environment env) {
        this.env = env;
    }

    private Properties additionalProperties() {
        final Properties properties = new Properties();
        HIBERNATE_MAPPINGS.entrySet().forEach(entry -> {
            final String property = env.getProperty(entry.getValue());
            if (property != null) {
                LOG.debug("{}: {}", entry.getValue(), property);
                properties.setProperty(entry.getKey(), property);
            }
        });
        return properties;
    }

    @Bean
    LocalContainerEntityManagerFactoryBean entityManagerFactory(final DataSource dataSource,
            final JpaVendorAdapter jpaVendorAdapter) {
        final LocalContainerEntityManagerFactoryBean factoryBean =
                new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setMappingResources("hbm/user.xml");
        factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        factoryBean.setJpaProperties(additionalProperties());
        return factoryBean;
    }

}

可以看到,DataSource和JpaVendorAdapter都是从Spring Boot自动配置中提取的。