当使用miltiple数据源时,hibernate envers无法正常工作

时间:2018-02-12 10:12:34

标签: spring hibernate spring-boot datasource hibernate-envers

当我只使用一个数据源时,hibernate envers运行良好(不使用任何config.java。只需设置application.properties)。但是使用多个数据源(使用config.java,相同的数据库,不同的用户),envers无法正常工作并记录oracle错误消息ORA-00942。 审计表位于DB#1中。我该怎么办?

spring boot 1.5.6

application.properties

#################################
#   DataBase #1 (Default)
#################################
spring.datasource.initialize=true
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:orcl
spring.datasource.username=id_1
spring.datasource.password=pw_1
spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver

#################################
#   DataBase #2(Additional)
#################################
db2.datasource.initialize=true
db2.datasource.url=jdbc:oracle:thin:@localhost:1521:orcl
db2.datasource.username=db_2
db2.datasource.password=pw_2
db2.datasource.driverClassName=oracle.jdbc.driver.OracleDriver

config.java

package com.dev;

import javax.sql.DataSource;

import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
public class DataBaseConfig {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource defaultDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "defaultEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {


        return builder.dataSource(defaultDataSource())
                .packages("com.dev.core.**", "com.dev.ext.**")
                .build();
    }

    @Primary
    @Bean(name = "defaultTransactionManager")
    PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactory(builder).getObject());
    }

    @Configuration
    @EnableJpaRepositories(basePackages= {"com.dev.core.**", "com.dev.ext.**"},
            entityManagerFactoryRef = "defaultEntityManagerFactory", transactionManagerRef = "defaultTransactionManager")
    static class DefaultJpaRepositoriesConfig {
    }

    /*Additional Data Source - NCRM*/
    @Bean
    @ConfigurationProperties(prefix = "db2.datasource")
    public DataSource ncrmDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "ncrmEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean ncrmEntityManagerFactory(EntityManagerFactoryBuilder builder) {

        return builder.dataSource(ncrmDataSource())
                .packages("com.dev.ext.ncrm.*.domain")
                .build();
    }

    @Bean(name = "ncrmTtransactionManager")
    PlatformTransactionManager ncrmTransactionManagerMain(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(ncrmEntityManagerFactory(builder).getObject());
    }

    @Configuration
    @EnableJpaRepositories(
            basePackages="com.dev.ext.ncrm.*.repo",
            entityManagerFactoryRef = "ncrmEntityManagerFactory",
            transactionManagerRef = "ncrmTtransactionManager")
    static class ncrmJpaRepositoriesConfig {
    }
}

defaultDO.java

package com.dev.core.domain;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.ColumnResult;
import javax.persistence.ConstructorResult;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.SqlResultSetMapping;
import javax.persistence.Table;

import org.hibernate.annotations.NamedNativeQuery;
import org.hibernate.envers.AuditTable;
import org.hibernate.envers.Audited;

import lombok.Data;

@Data
@Entity
@Table(name = "tb_category")
@Audited
@AuditTable("tx_category_audit")
public class CategoryDO {

    //codes 

}

2 个答案:

答案 0 :(得分:3)

首先在application.properties文件中添加hibernate方言,如下所示:两个数据源:

spring.datasource.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
spring.secondDatasource.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect

然后请重写如下配置

package com.multisource.poc.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
public class ApplicationConfiguration {

    @Value("${spring.datasource.hibernate.dialect}")
    private String oracleDialect;

    @Value("${spring.secondDatasource.hibernate.dialect}")
    private String postgresDialect;

    @Primary
    @Bean(name = "oracleDB")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource oracleDataSource() {
        return  DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "oracleEM")
    public LocalContainerEntityManagerFactoryBean oracleEntityManagerFactory(
            EntityManagerFactoryBuilder builder) {

        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", oracleDialect);

        LocalContainerEntityManagerFactoryBean emf = builder
                .dataSource(oracleDataSource())
                .packages("entitypackageOne")
                .persistenceUnit("oraclePU")
                .build();

        emf.setJpaProperties(properties);

        return emf;

    }


    @Bean(name = "postgresDB")
    @ConfigurationProperties(prefix = "spring.secondDatasource")
    public DataSource postgresDataSource() {
        return  DataSourceBuilder.create().build();
    }

    @Bean(name = "postgresEM")
    public LocalContainerEntityManagerFactoryBean postgresEntityManagerFactory(
            EntityManagerFactoryBuilder builder) {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", postgresDialect);

        LocalContainerEntityManagerFactoryBean emf = builder
                .dataSource(postgresDataSource())
                .packages("entitypackageTwo")
                .persistenceUnit("postgresPU")
                .build();

        emf.setJpaProperties(properties);

        return emf;
    }


}

现在您有两个不同的EntityManager可供使用。样本就像

@Repository
public class OracleDao implements InterOracle {

    private EntityManager entityManager;

    @Autowired
    public OracleDao(@Qualifier("oracleEM") EntityManager entityManager) {
        this.entityManager = entityManager;
    }

}


@Repository
public class PostgresDao implements InterPostGres{
    private static final Logger LOG
            = LoggerFactory.getLogger(PostgresDao.class);


    private EntityManager entityManager;

    @Autowired
    public PostgresDao(@Qualifier("postgresEM") EntityManager entityManager) {
        this.entityManager = entityManager;
    }

}

这就是我的应用程序使用两种不同数据源的方式。

答案 1 :(得分:0)

用户db_2 / pw_2是否具有访问数据库所需的权限?