2015-04-23 155 views
1

我有一个简单的Spring Boot应用程序与2个外部罐子。每个jar使用Spring JPA并完全配置为独立工作。春季启动与多个数据源和外部配置,春季JPA

Jar1

JPA库

@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; 
    } 
} 

第二罐子看起来几乎一样Jar1,除了Bean和包名

@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; 
    } 
} 

运行在Jar1这个主类提供了预期的效果。(同为Jar2)

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()); 

     } 
    } 
} 

这是启动类我的春节,启动应用程序

@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); 
    } 

} 

服务器开始机智的hout的问题,但在配置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 

下一个问题是数据库访问。春天犯规知道它应该使用的事务管理器

: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: aisjpatransactionManager,onlinejpaTransactionManager 

设置一个TX经理为@Primary解决了上述问题,但与其他的lib未发现表,错误配置TX经理/持久性单元的原因结束。

也许我的问题是LocalContainerEntityManagerFactoryBean的每个单独的jar的创建。相反,我应该使用下面的代码来设置我的数据库连接,但这会打破我个人的库。

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(); 
} 

我怎样才能让每一个人罐子的春天启动的应用程序内工作。

这里是一个链接,用Sping Boot设置多个数据源,但我不想在Spring Boot应用程序中配置我的库数据源。

Multiple data source and schema creation in Spring Boot

回答

1

的问题是错误的属性值的注入,可能是由PropertyPlaceholderConfigurer在每个罐子的静态调用引起的。

要么使用

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

    @Autowired 
    private Environment env; 

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

还是留给PropertyPlaceholderConfigurer的静态调用,但在你的application.properties前缀属性,使每个属性值是在整个应用程序的独特

jdbc.driverClassName=oracle.jdbc.OracleDriver 

jar1.jdbc.driverClassName=oracle.jdbc.OracleDriver