首页 文章

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

提问于
浏览
0

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

- 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公共类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启动失败
org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'parameterControllerImpl'的bean时出错:不满意
通过字段'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

    堆栈跟踪的最后一行是一条线索: 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")
    

相关问题