Hibernate Envers因@Converter和AttributeConverter而失败(JPA 2.1)

我正在使用带有Envers的Hibernate 4.3.4和MySql 5.6。

如果没有JPA 2.1转换器,下面的Party实体将在Configuration.buildSessionFactory()失败,因为Hibernate不知道如何处理Name类:

 @Entity @Audited public class Party { protected Name name; ... } 

例外是:

 org.hibernate.MappingException: Could not determine type for: ModuloADM.Party.Name, at table: Party, for columns: [org.hibernate.mapping.Column(name)] 

要解决此问题,我然后添加此转换器:

 @Converter (autoApply=true) public class NametoStringConverter implements AttributeConverter { ... } 

现在exception变为:

 org.hibernate.MappingException: Could not determine type for: BasicType adapter for AttributeConverter, at table: History_Party, for columns: [org.hibernate.mapping.Column(name)] 

现在,这在Party实体的Envers审核表中失败了。 请注意, History_Party是审计表的名称,由config.setProperty("org.hibernate.envers.audit_table_prefix", "History_")

完整的堆栈跟踪是:

 org.hibernate.MappingException: Could not determine type for: BasicType adapter for AttributeConverter, at table: History_Party, for columns: [org.hibernate.mapping.Column(name)] at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:336) at org.hibernate.tuple.PropertyFactory.buildEntityBasedAttribute(PropertyFactory.java:246) at org.hibernate.tuple.entity.EntityMetamodel.(EntityMetamodel.java:227) at org.hibernate.persister.entity.AbstractEntityPersister.(AbstractEntityPersister.java:520) at org.hibernate.persister.entity.SingleTableEntityPersister.(SingleTableEntityPersister.java:148) at sun.reflect.GeneratedConstructorAccessor43.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:525) at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163) at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135) at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:401) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857) 

我该如何解决这个问题? Envers甚至与AttributeConverters兼容吗?

尝试在Party Entity中使用@Convert。 有时autoApply标志不起作用

 @Entity @Audited public class Party { @Convert(converter = NametoStringConverter.class) protected Name name; ... } 

这似乎是Hibernate Envers(HHH-9042)的一个已知问题 。

一个简单的解决方法是手动调用Convter和一个额外的瞬态字段,如下所示:

 @Entity public class Party { protected Name name; @Transient protected String nameString; //... public void setName(Name name) { this.nameString = (new NametoStringConverter()).convertToDatabaseColumn(name); this.name = name; } //... public void setNameString(String nameString) { this.name = (new NametoStringConverter()).convertToEntityAttribute(nameString); this.nameString = nameString; } } 

根据转换函数,可以通过使代码static并导入它们来进一步简化代码。

我在exception中看到了文本“GeneratedConstructorAccessor43”。 可能是您需要一个公共的void构造函数,以便JPA可以创建NametoStringConverter的实例。

默认构造函数应该工作,但检查是否有另一个具有receive参数或不公开的构造函数。

我遇到了同样的问题,我发现它只在我没有将@Column注释与columnDefinition =“VARCHAR(255)”放到枚举时才发生。 所以我认为这比hibernate跟踪器更好。