2024年9月11日 星期三

做 Hibernate envers 設定時遇到的坑

這篇算是延續先前《SpringBoot 使用多個資料庫連線》的狀況

我今天想要使用Hibernate envers來處理資料的版控。

原先我是這樣處理的:

  1. pom.xml 加上library

    <dependency>
    	<groupId>org.hibernate</groupId>
    	<artifactId>hibernate-envers</artifactId>
    </dependency>
  2. application.properties 加上設定

    spring.jpa.properties.hibernate.envers.audit_table_suffix=_rev
    spring.jpa.properties.hibernate.envers.revision_field_name=rev
    spring.jpa.properties.hibernate.envers.revision_type_field_name=revtype
    
  3. Hibernate Entity 加上 @Audit
    import javax.persistence.Entity;
    import javax.persistence.Table;
    
    import org.hibernate.envers.Audited;
    
    @Entity
    @Audit
    @Table(name = "my_entity")
    class MyEntity{
    	// 中略
    }

然而,實際執行時,Hibernate 處理版控資料時,都想要存入 my_entity_AUD,即

insert into `my_entity_AUD` 
# 下略

我也嘗試過 properties 改成 org.hibernate.envers.audit_table_suffix=_revspring.jpa.properties.org.hibernate.envers.audit_table_suffix=_rev之類的修改;真沒辦法,問 Chat GPT ,都沒得到解答


先前也提到,這篇文章是延續《SpringBoot 使用多個資料庫連線》的。其實原因正是因為我有自定 EntityManagerFactory,所以 properties 沒有作用。

解決辦法就是去修改 EntityManagerFactory

原先是

@Bean("MySQLDBEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean EntityManagerFactory(
		@Qualifier("MySQLDBDataSource") DataSource ds) {
	EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), new HashMap<>(), null);
	return builder.dataSource(ds)
		.packages("org.example.database.db")
		.persistenceUnit("mysqldb") 
		.build();
}

改成

@Bean("MySQLDBEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean EntityManagerFactory(
		@Qualifier("MySQLDBDataSource") DataSource ds) {

	/*
	 * 將 properties 加在這裡
	 */
	Map<String, Object> prop = new HashMap<>(); 
	prop.put("spring.jpa.properties.hibernate.envers.audit_table_suffix", "_rev");
	prop.put("spring.jpa.properties.hibernate.envers.revision_field_name", "rev");
	prop.put("spring.jpa.properties.hibernate.envers.revision_type_field_name", "revtype");

	EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), prop, null);
	return builder.dataSource(ds)
		.packages("org.example.database.db")
		.persistenceUnit("mysqldb") 
		.build();
}

沒有留言:

張貼留言