2015-04-23 201 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