2016-07-12 114 views
1

我试图将我的审计表保存在另一个模式,但保持与审计表相同名称的表。我没有问题,改变后缀或使用另一种模式,但是当我设置后缀为空字符串,我发现了以下错误:休眠Envers审计表没有后缀

Caused by: org.hibernate.DuplicateMappingException: Duplicate class/entity mapping com.logique...User 

我猜这个错误发生,因为我有两个表(但使用不同的模式),我正确设置了“org.hibernate.envers.default_schema”和“hibernate.default_schema”参数,但我并没有预料到这个问题。

+0

因此,您在数据库的默认模式中拥有未经审计的JPA实体,并且已经在另一个明确设置的模式中获得了您的Envers审计实体表?什么版本的Hibernate? – Naros

+0

Hi @Naros!再次感谢帮助=)。确切地说,我在数据库的默认架构中拥有未经审计的实体,并且在另一个明确设置的架构中,我的Envers审计了实体表。我正在使用休眠4.3.11-FINAL –

回答

1

当Hibernate执行其元数据收集过程时,它首先读取所有注释的实体类并按名称注册它们中的每一个。此外,由于Envers处理其元数据并将该信息提供给Hibernate,Hibernate随后将依次通过名称注册每个经审计的实体。

这里的问题是,如果没有提供后缀或前缀,Hibernate将Envers的映射视为已注册的实体名称,因为没有前缀/后缀,它们的命名与它们生成的源实体完全相同从,导致这个错误。

org.hibernate.DuplicateMappingException: Duplicate class/entity mapping 

有一个解决方法,但它可能是繁琐的,取决于您可能有审计实体的数量。我已经在5.x上测试过了,我可能怀疑这应该在4.3.x上运行。

  1. 设置audit_table_prefixaudit_table_suffix配置属性。这是一个必须,因为这将强制来自Envers的元数据是唯一命名为Hibernate的可持久对象。如果不这样做,您将继续从上方获取重复的映射错误。
  2. 对于每个审计实体,明确添加一个@AuditTable注释,您可以在其中专门将审计表名称设置为与为您的实体生成的名称相同,无论它是基于类名还是具有名称属性的现有@Table

因此,作为一个例子:

@Entity 
@Table(name = "my_table") 
@AuditTable("my_table") 
public class MyTableEntity { 
    /* stuff */ 
} 

所以用这个配置,你就可以有一个模式中你Envers表,另一个主要的实体表,这两个模式有其表的名字相同。

希望这会有所帮助。

+0

Hi @Naros,再次感谢您的帮助,抱歉花了这么长时间来测试您的答案。我收到两条警告:“WARN:GenerationTarget遇到异常接受命令:无法执行命令[alter table audit.person drop constraint FK9brsg4fcuo22u7e7oxa9g1tqn]”和“WARN:GenerationTarget遇到异常接受命令:无法执行命令[drop sequence hibernate_sequence] ”。对此有何想法? –

+0

我遗留了我用来在github上测试的代码,https:// github。com/Teless/TesteEnvers,保持尽可能简单2类和项目描述 –

+0

两个警告的堆栈跟踪我相信这些警告是由于Hibernate试图在审计表和实体表之间创建外键另一个模式),我说得对吗? –