【问题标题】:Spring JPA Audit fails with multiple datasourcesSpring JPA 审计因多个数据源而失败
【发布时间】:2019-11-26 18:16:58
【问题描述】:

有很多网站解释如何set up Spring auditing。而且我不打算在这里重新讨论所有这些。我的问题是,在 Spring Auditing 工作了很长时间之后,我们有了一个新的要求。

我们现在必须添加第二个数据源来读取不同的 Oracle 数据库。这似乎也可以正常工作。然而,当我添加第二个数据源时,审计已停止工作。

这个错误看似不言自明:

原因:java.sql.SQLSyntaxErrorException: ORA-00904: "RESTENDPOI0_"."LASTCHANGEDDATE": 标识符无效

问题似乎是 LAST_CHANGED_DATE 现在缺少下划线。

使用 Spring Boot 2.1.3.RELEASE,当然不需要声明数据源(从 application.yml 获取)、entityManager 和事务管理器。

但是当添加第二个数据源时,除了 application.yml 中的新定义之外,我还必须声明两个新类。一个用于 PrimaryDataSource(如下所示),一个用于辅助(未显示,这是一个只读数据源,审计不是它的一部分)。

显而易见的答案是,手动定义这些 Bean 破坏了 EventListener。但我无法将这种观察转化为任何类型的解决方案。

(显然)相关代码在这里:

审计模型

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditModel implements Serializable {

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "LAST_CHANGED_DATE", nullable = true)
@LastModifiedDate
private Timestamp lastChangedDate;
...

要审核的实体

@Entity
@Table(name = "ENDPOINT")
public class Endpoint extends AuditModel {
    private String  endpointName;
    private String  httpVerb;

主要数据源

@Configuration
@EnableJpaAuditing
@EnableJpaRepositories(basePackageClasses={ xxx.scheduler.model.Endpoint.class, xxx.scheduler.repository.EndpointRepository.class} ,
entityManagerFactoryRef = "dashboardEntityManagerFactory",
transactionManagerRef = "dashboardTransactionManager")

public class PrimaryDataSource {

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

@Bean
@Primary
public LocalContainerEntityManagerFactoryBean dashboardEntityManagerFactory()  {
    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
    emf.setDataSource(dashboardDataSource());
    emf.setPersistenceUnitName("schedulerPrimaryPU");
    emf.setJpaDialect(new HibernateJpaDialect());
    emf.setJpaVendorAdapter(jpaVendorAdapter());
    emf.setPackagesToScan(new String[] { "xxx.dashboardscheduler.model" });
    return emf;
}

@Bean
@Primary
public PlatformTransactionManager dashboardTransactionManager(){
    JpaTransactionManager transactionManager
            = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(
    dashboardEntityManagerFactory().getObject() );
    return transactionManager;
}

@Bean
public JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setDatabase(Database.ORACLE);
    vendorAdapter.setDatabasePlatform("org.hibernate.dialect.Oracle10gDialect");
    vendorAdapter.setShowSql(false);
    return vendorAdapter;
}

}

【问题讨论】:

    标签: hibernate spring-boot spring-data-jpa


    【解决方案1】:

    我也遇到过类似的问题,和审计本身无关。不知何故,第二个数据源没有采用字段命名约定,因此系统将lastChangedDate 映射到LASTCHANGEDDATE,而它必须是last_changed_datedashboardEntityManagerFactory 中的这些属性解决了这个问题:

    Map<String, Object> props = new HashMap<>();
    props.put("hibername.implicit_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
    props.put("hibername.physical_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
    emf.setJpaPropertyMap(props);
    

    【讨论】:

      猜你喜欢
      • 2011-07-15
      • 1970-01-01
      • 2019-01-27
      • 2014-05-28
      • 1970-01-01
      • 2016-05-26
      • 2016-08-22
      • 2021-03-11
      • 2021-12-03
      相关资源
      最近更新 更多