当Hibernate执行其元数据收集过程时,它首先读取所有注释的实体类并按名称注册它们中的每一个。此外,由于Envers处理其元数据并将该信息提供给Hibernate,Hibernate随后将依次通过名称注册每个经审计的实体。
这里的问题是,如果没有提供后缀或前缀,Hibernate将Envers的映射视为已注册的实体名称,因为没有前缀/后缀,它们的命名与它们生成的源实体完全相同从,导致这个错误。
org.hibernate.DuplicateMappingException: Duplicate class/entity mapping
有一个解决方法,但它可能是繁琐的,取决于您可能有审计实体的数量。我已经在5.x上测试过了,我可能怀疑这应该在4.3.x上运行。
- 设置
audit_table_prefix
或audit_table_suffix
配置属性。这是一个必须,因为这将强制来自Envers的元数据是唯一命名为Hibernate的可持久对象。如果不这样做,您将继续从上方获取重复的映射错误。
- 对于每个审计实体,明确添加一个
@AuditTable
注释,您可以在其中专门将审计表名称设置为与为您的实体生成的名称相同,无论它是基于类名还是具有名称属性的现有@Table
。
因此,作为一个例子:
@Entity
@Table(name = "my_table")
@AuditTable("my_table")
public class MyTableEntity {
/* stuff */
}
所以用这个配置,你就可以有一个模式中你Envers表,另一个主要的实体表,这两个模式有其表的名字相同。
希望这会有所帮助。
因此,您在数据库的默认模式中拥有未经审计的JPA实体,并且已经在另一个明确设置的模式中获得了您的Envers审计实体表?什么版本的Hibernate? – Naros
Hi @Naros!再次感谢帮助=)。确切地说,我在数据库的默认架构中拥有未经审计的实体,并且在另一个明确设置的架构中,我的Envers审计了实体表。我正在使用休眠4.3.11-FINAL –