当前位置: 首页 > 知识库问答 >
问题:

带有多个数据源和外部配置的Spring Boot,Spring JPA

吴靖
2023-03-14

我有一个简单的Spring引导应用程序与2个外部罐子。每个jar都使用Spring JPA,并且完全配置为独立工作。

JAR1

@Repository
public interface QuarterRepository extends JpaRepository<Quarter, Long>{


}
@Entity
public class Quarter implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;...
@Configuration
@Import({RepositoryConfig.class})
public class OnlineJpaAppConfig{

    @Bean(name = "onlinejpaAppConfigConfigurer")
    public static PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer()    {        
        PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
        ppc.setLocation(new ClassPathResource("/de/comp/onlinejpa/application.properties"));
        ppc.setIgnoreUnresolvablePlaceholders(true);
        return ppc;
    }
}  


@Configuration
@EnableJpaRepositories(basePackages = {"de.comp.onlinejpa.repository"},
        entityManagerFactoryRef = "onlinejpaentityManagerFactory",
        transactionManagerRef = "onlinejpaTransactionManager")
@EnableTransactionManagement
public class RepositoryConfig {

    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Value("${hibernate.dialect}")
    private String hibernateDialect;
    @Value("${hibernate.show_sql}")
    private String hibernateShowSql;
    @Value("${hibernate.hbm2ddl.auto}")
    private String hibernateHbm2ddlAuto;

    private static final String QUALIFIER = "onlinejpa";

    @Bean(name = "onlinejpaentityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[]{"de.comp.onlinejpa.entity"});
        em.setPersistenceUnitName("onlinejpa");
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());

        return em;
    }

    @Bean(name = "onlinejpaDataSource")
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean(name = "onlinejpaTransactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier(value = "onlinejpaentityManagerFactory") EntityManagerFactory onlinejpaentityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(onlinejpaentityManagerFactory);

        return transactionManager;
    }

    @Bean(name = "onlinejpaExceptionTranslation")
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    Properties additionalProperties() {

        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", hibernateHbm2ddlAuto);
        properties.setProperty("hibernate.dialect", hibernateDialect);
        return properties;
    }
}
@EnableJpaRepositories(basePackages = {"de.comp.aisjpa.repository"}, 
        entityManagerFactoryRef = "aisjpaentityManagerFactory",
        transactionManagerRef = "aisjpatransactionManager")
@EnableTransactionManagement
public class RepositoryConfig {

    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Value("${hibernate.dialect}")
    private String hibernateDialect;
    @Value("${hibernate.show_sql}")
    private String hibernateShowSql;
    @Value("${hibernate.hbm2ddl.auto}")
    private String hibernateHbm2ddlAuto;

     private static final String QUALIFIER = "aisjpa";


    @Bean(name = "aisjpaentityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(aisdataSource());
        em.setPackagesToScan(new String[]{"de.comp.aisjpa.entity"});
        em.setPersistenceUnitName("ais");
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());

        return em;
    }



    @Bean(name = "aisjpadatasource")
    public DataSource aisdataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }


    @Bean(name = "aisjpatransactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier(value = "aisjpaentityManagerFactory") EntityManagerFactory aisjpaentityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(aisjpaentityManagerFactory);

        return transactionManager;
    }


    @Bean(name = "aisjpaexceptionTranslation")
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", hibernateHbm2ddlAuto);
        properties.setProperty("hibernate.dialect", hibernateDialect);
        return properties;
    }
}
public class App {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(OnlineJpaAppConfig.class);

        QuarterRepository quarterRepository = ctx.getBean("quarterRepository", QuarterRepository.class);

        List<Quarter> quarters = quarterRepository.findAll();

        for (Quarter quarter : quarters) {

            System.out.println(quarter.getQuarter());

        }
    }
}

这是我的Spring Boot应用程序的启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class } )
@Import({ KVLdapAppConfig.class, OnlineJpaAppConfig.class,AISAppConfig.class})

public class ServerApplication {

    public static void main(String[] args) {

        SpringApplication.run(ServerApplication.class, args);
    }

}

服务器启动时没有任何问题,但在配置jpa内容时存在一些问题。持久性单元ais的配置应使用Oracle方言和驱动程序。看来它拿起了JAR1的配置。

Building JPA container EntityManagerFactory for persistence unit 'onlinejpa'
HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
HHH000412: Hibernate Core {4.2.0.Final}
HHH000206: hibernate.properties not found
HHH000021: Bytecode provider name : javassist
HHH000204: Processing PersistenceUnitInfo [


HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
HHH000397: Using ASTQueryTranslatorFactory
Loaded JDBC driver: com.mysql.jdbc.Driver
Building JPA container EntityManagerFactory for persistence unit 'ais'
HHH000204: Processing PersistenceUnitInfo [


HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
HHH000400: Using dialect: **org.hibernate.dialect.MySQL5Dialect**
HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
HHH000397: Using ASTQueryTranslatorFactory
Loaded JDBC driver: com.mysql.jdbc.Driver

下一个问题是数据库访问。Spring不知道应该使用哪个事务管理器

: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: aisjpatransactionManager,onlinejpaTransactionManager
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
        EntityManagerFactoryBuilder builder) {
    Map<String, Object> properties = new HashMap<String, Object>();
    properties.put("hibernate.hbm2ddl.auto", "create");
    return builder
            .dataSource(internalDataSource())
            .packages("package here")
            .persistenceUnit("onlinjpa")
            .properties(properties)
            .build();
}

共有1个答案

徐晔
2023-03-14

问题是注入了错误的属性值,可能是在每个JAR中静态调用PropertyPlaceHolderConfigureer造成的。

或者使用

    @PropertySource("classpath:/de/comp/aisjpa/application.properties")
    public class RepositoryConfig

    @Autowired
    private Environment env;

    dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
    ....

或者将静态调用保留给PropertyPlaceHolderConfigureer,但在application.properties中为属性加上前缀,这样每个属性值在整个应用程序中都是唯一的

jdbc.driverClassName=oracle.jdbc.OracleDriver

jar1.jdbc.driverClassName=oracle.jdbc.OracleDriver
 类似资料:
  • 我有两个配置文件(“autoContido”和“weblogic”),其中每个配置文件都有两个配置类,因为我使用的是两个数据源。 我已经将特定数据源中的bean注释为@Primary,而另一个数据源配置类中的bean不是@Primary,但我对它们的命名不同。 我以为使用@主注释就不会有像下面这样的错误,但我仍然得到它们。有人能帮我看看问题出在哪里吗? 我尝试使用@Primary annotati

  • 本文向大家介绍springboot + mybatis配置多数据源示例,包括了springboot + mybatis配置多数据源示例的使用技巧和注意事项,需要的朋友参考一下 在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源。 代码结构: 简要原理: 1)DatabaseType列出所有的数据源的key---key 2)DatabaseContextHolder是一个线

  • 问题内容: 我正在使用Spring和Hibernate,Spring的配置如下。如何配置两个数据源, session factories。使用注释管理事务。请指教 问题答案: 在Hibernate DAO中,我们可以使用@Qualifier注释,如下所示连接2个会话工厂

  • springboot 配置多源数据库问题。 测试了一下springboot配置多源数据库,mysql和postgresql,yml配置如下: 运行程序,出现如下错误: …… 9:30:59:048] [INFO] - org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.prepareWebA

  • 我正在尝试使用两个数据源与我的SpringBoot应用程序,但无法获得第二个数据源自动连接。我尝试过很多事情,但这是我最接近的一次: 我的Yaml文件: 这是我到目前为止最接近的一次。我之所以说它是最接近的,是因为如果我删除@qualifier,那么我的两个dao方法实际上都可以工作,假设SECOND_SELECT语句对于我的DB1是有效的SQL语句。当我为非主datasouce输入@Qualif

  • 在springboot应用程序中,我有一个jar,然后是一个子目录config with application。属性,applicationContext。xml和log4j。。。属性文件。 我正在尝试外部化log4j配置。application.properties是这样外部化的。 但是,当springboot运行时,它使用jar文件中的log4j配置文件。通过使用-Dlog4j.debug选