Spring-boot&多个数据库连接:autowire服务不起作用

时间:2017-12-01 14:02:07

标签: database spring-boot connection vaadin8

我正在编写一个需要连接至少2个数据库的Spring-boot应用程序。     每个数据库有1个项目,用于定义域,每个数据库1个项目,以便为UI定义服务,1个Vaadin项目用于UI。

 - a business domain entity sample
    @Entity
    @Table(name="T_PARAMETER")
    public class Parameter extends BaseIdEntity implements Serializable {

    @Column(name="par_cls")
    @NotNull
    private String parameterClass;

    @Column(name="par_cd")
    @NotNull
    private String parameterCode;

    @Column(name="par_lan")
    @NotNull
    private String language;

    @Column(name="par_sht_val")
    @NotNull
    private String parameterValueShort;

    @Column(name="par_lng_val")
    @NotNull
    private String parameterValueLong;

 - a authentication domain entity sample

    @Entity
    @Table(name="t_user", schema="authenticate")
    public class User extends BaseIdEntity implements Serializable {

    @Id
    @Column(name="user_cd")
    private String userCode;

    @Column(name="pwd")
    @NotNull
    private String password;

    @Column(name="new_pwd_req")
    @NotNull
    private boolean passwordRequired;

    @Column(name="acc_lck")
    @NotNull
    private boolean accountLocked;

There are repositories onto these 2 entities beans, they just extends the JpaRepository as hereunder:

public interface ParameterRepository extends JpaRepository<Parameter,Integer>{}
  • 服务定义如下:

    @Service
    @Transactional(transactionManager="authenticateTransactionManager")
    public class ServiceParameterImpl implements ServiceParameter {
    
    private final static Logger log = LoggerFactory.getLogger(ServiceParameterImpl.class);
    
    @Autowired
    private ParameterRepository parameterRepository;
    
    @Override
    @Transactional(readOnly=true,transactionManager="authenticateTransactionManager")
    public List<Parameter> findParameterHeader(String filter) {
    

    ... / ...

  • 客户端应用程序为:

    @SpringBootApplication
    @Configuration
    @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class
        , HibernateJpaAutoConfiguration.class
        , DataSourceTransactionManagerAutoConfiguration.class })
    @ComponentScan(
        basePackages= {
                "org.associative.ui"
                ,"org.associative.service"
                })
    @Import({AssociativityConfiguration.class, AuthenticateConfiguration.class})
    public class Application {
    
    private final static Logger log = LoggerFactory.getLogger(Application.class);
    
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    

    }

  • 和配置:

    @Configuration
    @EnableTransactionManagement
    @EntityScan(basePackages= "org.associative.domain.associativity")
    @EnableJpaRepositories(
        basePackages = "org.associative.domain.associativity.repository"
        , entityManagerFactoryRef = "associativityEntityManager"
        , transactionManagerRef = "associativityTransactionManager"
        )
        @ConfigurationProperties(prefix = "db.associativity")
        public class AssociativityConfiguration {
    
    private final static Logger log = LoggerFactory.getLogger(AssociativityConfiguration.class);
    
    @Autowired
    private Environment env;
    
    private final static String ASSOCIATIVITY_DRIVER_CLASS_NAME = "db.associativity.classname";
    private final static String ASSOCIATIVITY_URL = "db.associativity.connectionUrl";
    private final static String ASSOCIATIVITY_USERNAME = "db.associativity.username";
    private final static String ASSOCIATIVITY_PASSWORD = "db.associativity.password";
    
    private final static String HIBERNATE_DIALECT = "hibernate.dialect";
    
    @Bean(name = "associativityDataSource")
    public DataSource datasource() {
        DataSource dataSource = DataSourceBuilder.create()
                .driverClassName(env.getProperty(ASSOCIATIVITY_DRIVER_CLASS_NAME))
                .url(env.getProperty(ASSOCIATIVITY_URL))
                .username(env.getProperty(ASSOCIATIVITY_USERNAME))
                .password(env.getProperty(ASSOCIATIVITY_PASSWORD)).build();
    
        if (log.isTraceEnabled())
            log.trace(String.format("associativityConfiguration datasource:%s", dataSource.toString()));
    
        return dataSource;
    }
    
    @Bean(name = "associativityEntityManager")
    @PersistenceContext(unitName = "associativity")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("associativityDataSource") DataSource dataSource) {
    
        Map<String, Object> jpaProperties = new HashMap<>();
        jpaProperties.put(HIBERNATE_DIALECT, env.getProperty(HIBERNATE_DIALECT));
    
        LocalContainerEntityManagerFactoryBean em = builder.dataSource(dataSource)
                .packages("org.associative.domain.authenticate").persistenceUnit("pu_associativity").properties(jpaProperties)
                .build();
        em.setJpaPropertyMap(jpaProperties);
    
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(adapter); // not mandatory definition
    
        return em;
    }
    
    @Bean(name = "associativityTransactionManager")
    public PlatformTransactionManager associativityTransactionManager(
            @Qualifier("associativityEntityManager") EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }
    

    }

  • @Configuration
    @EnableTransactionManagement
    @EntityScan(basePackages= "org.associative.domain.authenticate")
    @EnableJpaRepositories(
        basePackages = "org.associative.domain.authenticate.repository"
        , entityManagerFactoryRef = "authenticateEntityManager"
        , transactionManagerRef = "authenticateTransactionManager"
        )
    @ConfigurationProperties(prefix="db.authenticate")
    public class AuthenticateConfiguration {
    
    private final static Logger log = LoggerFactory.getLogger(AuthenticateConfiguration.class);
    
    @Autowired
    private Environment env;
    
    private final static String AUTHENTICATE_DRIVER_CLASS_NAME= "db.authenticate.classname";
    private final static String AUTHENTICATE_URL = "db.authenticate.connectionUrl";
    private final static String AUTHENTICATE_USERNAME = "db.authenticate.username";
    private final static String AUTHENTICATE_PASSWORD = "db.authenticate.password";
    private final static String HIBERNATE_DIALECT = "hibernate.dialect";
    
    @Primary
    @Bean(name = "authenticateDataSource")
    public DataSource datasource() {
        DataSource dataSource = DataSourceBuilder.create()
                .driverClassName(env.getProperty(AUTHENTICATE_DRIVER_CLASS_NAME))
                .url(env.getProperty(AUTHENTICATE_URL))
                .username(env.getProperty(AUTHENTICATE_USERNAME))
                .password(env.getProperty(AUTHENTICATE_PASSWORD))
                .build();
    
        if ( log.isTraceEnabled()) log.trace(String.format("authenticateDataSource datasource:%s", dataSource.toString()));
    
        return dataSource;
    }
    
    @Primary
    @Bean(name="authenticateEntityManager")
    @PersistenceContext(unitName = "authenticate")
    //https://raymondhlee.wordpress.com/tag/enablejparepositories/
    public LocalContainerEntityManagerFactoryBean entityManagerFactory( 
            EntityManagerFactoryBuilder builder, @Qualifier("authenticateDataSource")DataSource dataSource) {
    
        Map<String,Object> jpaProperties = new HashMap<>();
        jpaProperties.put(HIBERNATE_DIALECT, env.getProperty(HIBERNATE_DIALECT));
    
        LocalContainerEntityManagerFactoryBean em = builder
                .dataSource(dataSource)
                .packages("org.associative.domain.authenticate")
                .persistenceUnit("pu_authenticate")
                .properties(jpaProperties)
                .build();
        em.setJpaPropertyMap(jpaProperties);
    
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(adapter); // not mandatory definition
    
        return em;
    }
    
    @Primary
    @Bean(name="authenticateTransactionManager")
    public PlatformTransactionManager authenticateTransactionManager(
            @Qualifier("authenticateEntityManager")EntityManagerFactory entityManagerFactory){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }
    

    }

    在构建客户端界面时使用自动装配构建服务时,我遇到了一个问题:

    @SpringUI     public class ParameterListView extends CssLayout实现Serializable {

    private final static Logger log = LoggerFactory.getLogger(ParameterListView.class);
    
    @Autowired
    private ParameterController controller;
    
    @PostConstruct
    private void initView() {
        if ( log.isTraceEnabled() ) log.trace(String.format("initView:%s", "no param"));
    
        Grid<Parameter> grid = new Grid<>();
        this.addComponent(grid);
    
        grid.setItems(controller.getParameterHeader(""));
    
        grid.addColumn(Parameter::getParameterClass);
        grid.addColumn(Parameter::getParameterValueShort);
        grid.addColumn(Parameter::getParameterValueLong);
    
2017-12-01 14:20:07.151 ERROR o.s.b.SpringApplication Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'parameterControllerImpl': Unsatisfied
     

通过字段'serviceParameter'表示的依赖关系;嵌套   例外是   org.springframework.beans.factory.UnsatisfiedDependencyException:   创建名为'serviceParameterImpl'的bean时出错:不满意   通过字段'parameterRepository'表示的依赖;嵌套   异常是org.springframework.beans.factory.BeanCreationException:   创建名为'parameterRepository'的bean时出错:调用   init方法失败;嵌套异常是   java.lang.IllegalArgumentException:不是托管类型:class   org.associative.domain.associativity.Parameter

我已经花了很多时间来解决多个数据库连接,因为我认为这个问题来自定义问题,但我现在不确定。     那么,为了解决这个问题,我应该注意什么呢。

非常感谢你。

1 个答案:

答案 0 :(得分:0)

堆栈跟踪的最后一行是一条线索:Not a managed type: class org.associative.domain.associativity.Parameter。 Hibernate不了解您的Parameter实体。

LocalContainerEntityManagerFactoryBean中设置要扫描到org.associative.domain.authenticate的软件包。您的参数实体不在此包中。

这应解决问题:

.packages("org.associative.domain.authenticate", "org.associative.domain.associativity")