如何在拥有两个数据源的情况下使用hql从数据库中获取部分对象?

时间:2017-06-21 14:10:49

标签: java hibernate spring-boot hql

这是我的问题。 我必须开发一个REST控制器,它从旧数据库中公开数据。 由于这个数据库设计糟糕(由较旧的开发人员设计),一些相​​关数据在另一个数据库中......

在这里,我从第一个数据库中获取一个用户,但是该用户的生日存储在第二个数据库中。

在我们可以找到用户生日的表格中,还有许多我没有考虑过的字段,这就是为什么我说的是部分对象。

我的hibernateConfig是这样的:

 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.util.Properties;

@Configuration
@EnableTransactionManagement
@ComponentScan({"com.project.persistence.config"})
public class HibernateJpaConfig {
@Autowired
Environment environment;
@Autowired
@Qualifier("dataSource")
private DriverManagerDataSource dataSource;

@Autowired
@Qualifier("secondDataSource")
private DriverManagerDataSource secondDataSource;

@Bean
@Primary
public LocalContainerEntityManagerFactoryBean entityManager() {
    final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(this.dataSource);
    em.setPackagesToScan(new String[] {"com.project.core.model"});
    final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    em.setJpaProperties(this.hibernateProperties());
    return em;
}

@Bean
public LocalContainerEntityManagerFactoryBean secondEntityManager() {
    final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(this.secondDataSource);
    em.setPackagesToScan(new String[] {"com.project.core.model"});
    final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    em.setJpaProperties(this.hibernateProperties());
    return em;
}

@Bean(name = "transactionManager")
@Autowired
public JpaTransactionManager txManager() {
    final JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManager().getNativeEntityManagerFactory());
    return txManager;
}

@Bean(name = "secondTransactionManager")
@Autowired
public JpaTransactionManager secondTxManager() {
    final JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(secondEntityManager().getNativeEntityManagerFactory());
    return txManager;
}

/**
 * To get the hibernate properties.
 *
 * @return The properties
 */
Properties hibernateProperties() {
    return new Properties() {
        {
            setProperty("hibernate.hbm2ddl.auto",
                HibernateJpaConfig.this.environment.getProperty("hibernate.hbm2ddl.auto"));
            setProperty("hibernate.dialect", HibernateJpaConfig.this.environment.getProperty("hibernate.dialect"));
        }
    };
  }
}

我的DAO是这样的:

import com.projet.core.model.Birthdate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Transactional("secondTransactionManager")
@Repository
public class BirthdateDao extends Dao<Birthdate>{
    private static final String QUERY =
        "SELECT new Birthdate(b.idBirthdate, b.birthdate, b.registrationNumber) FROM " + "Birthdate as b";
    public BirthdateDao() {
        this.persistentClass = Birthdate.class;
    }

    /**
     * @return list of birthdates
     */
    public List<Birthdate> getAllBirthdates() {
        return this.entityManager.createQuery(QUERY).getResultList();
    }
}

我的实体看起来像这样:

package com.projet.core.model;

import javax.persistence.*;

@Entity
@Table(name = "donneesPersonne")
public class Birthdate extends AEntity{
    @Column(nullable = false, columnDefinition = "TEXT", name = "matricule")
    private final String registrationNumber;
    @Column(columnDefinition = "TEXT", name = "dateNaissance")
    private final String birthdate;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "idDonneePersonne")
    private final Long idBirthdate;

    public Birthdate(final Long idBirthdate, final String birthdate, final String registrationNumber) {
        this.registrationNumber = registrationNumber;
        this.birthdate = birthdate;
        this.idBirthdate = idBirthdate;
    }

    public String getRegistrationNumber() {
        return this.registrationNumber;
    }

    public String getBirthdate() {
        return this.birthdate;
    }
}

但getAllBirthdates返回一个空列表(数据库中超过300行)。 你能帮我找出问题所在吗?

1 个答案:

答案 0 :(得分:0)

如果我是你,我会设计一个ETL过程来移动并停用旧数据库。 300行没什么,所以它应该相对容易。将数据合并到一个数据库后,可以避免这一切。