我正在使用带有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<Name, String>
{ ... }
现在异常改为:
org.hibernate.MappingException:
Could not determine type for:
BasicType adapter for AttributeConverter<Name,String>,
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<Name,String>,
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.<init>(EntityMetamodel.java:227)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:520)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(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.<init>(SessionFactoryImpl.java:401)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857)
我该如何解决这个问题? Envers甚至与AttributeConverters兼容吗?
答案 0 :(得分:1)
尝试在Party
实体中使用@Convert。有时autoApply
标志不起作用
@Entity
@Audited
public class Party
{
@Convert(converter = NametoStringConverter.class)
protected Name name;
...
}
答案 1 :(得分:1)
这似乎是known problem with 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
并导入代码来进一步简化代码。
答案 2 :(得分:0)
我在异常中看到了文本“GeneratedConstructorAccessor43”。可能是您需要一个公共的void构造函数,以便JPA可以创建NametoStringConverter的实例。
默认构造函数应该可以工作,但要检查是否有另一个带有receive参数的构造函数,或者不是public。
答案 3 :(得分:0)
我遇到了同样的问题,我发现它只是在我没有将@Column注释与columnDefinition =“VARCHAR(255)”放到枚举时才发生。所以我认为这比hibernate跟踪器更好。