8

我正在使用带有 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 兼容吗?

4

4 回答 4

1

这似乎是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和导入代码来进一步简化代码。

于 2014-08-24T16:01:00.783 回答
1

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

@Entity
@Audited
public class Party
    {
    @Convert(converter = NametoStringConverter.class)
    protected Name name;
    ...
    }
于 2014-03-13T03:39:34.413 回答
0

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

默认构造函数应该可以工作,但请检查您是否有另一个带有接收参数或不公开的构造函数。

于 2014-03-25T13:16:55.303 回答
0

我有同样的问题,我发现它只发生在我没有将带有 columnDefinition = "VARCHAR(255)" 的 @Column 注释放入枚举时。所以我认为这是一个比休眠跟踪器更好的解决方法。

于 2016-03-28T03:44:59.413 回答