Hibernate Envers使用@Converter和AttributeConverter失败(JPA 2.1) [英] Hibernate Envers fails with @Converter and AttributeConverter (JPA 2.1)

查看:374
本文介绍了Hibernate Envers使用@Converter和AttributeConverter失败(JPA 2.1)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Envers和MySql 5.6中使用Hibernate 4.3.4。



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

  @Entity 
@Audited
公共类派对
{
受保护的名称名称;
...
}

例外情况是:

  org.hibernate.MappingException:
无法确定类型:
ModuloADM.Party.Name,
at table:Party,列:[org.hibernate.mapping.Column(name)]

这个,然后我添加这个转换器:

$ $ p $ $ $ $ c $ @ $ $ $ $ $ b $ public class NametoStringConverter
实现了AttributeConverter< Name,String>
{...}

现在异常变为:

  org.hibernate.MappingException:
无法确定类型:
AttributeConverter的BasicType适配器< Name,String> ;, $表格中的b $ b:History_Party,列:[org.hibernate.mapping.Column(name)]

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



完整的堆栈跟踪是:

 无法确定类型:
AttributeConverter的BasicType适配器< Name,String>,
表:History_Party,列:[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 (构造函数.java:525)$ b $。 $ b 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兼容吗?

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



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

  @Entity 
public class派对{

受保护的名称;

@Transient
保护字符串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 并导入它们来进一步简化代码。


I am using Hibernate 4.3.4 with Envers, and MySql 5.6.

Without a JPA 2.1 converter, the Party entity below fails at Configuration.buildSessionFactory() as it should, since Hibernate doesn't know what to do with the Name class:

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

The exception is:

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

To fix this, I then add this converter:

@Converter (autoApply=true)
public class NametoStringConverter
      implements AttributeConverter<Name, String>
    { ... }

And the exception now changes to:

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)]

This is now failing at the Envers auditing table for the Party entity. Note that History_Party is the name of the audit table, as chosen by config.setProperty("org.hibernate.envers.audit_table_prefix", "History_").

The complete stacktrace is:

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)

How do I solve this? Is Envers even compatible with AttributeConverters?

解决方案

This seems to be a known problem with Hibernate Envers (HHH-9042).

A simple workaround would be a manual invocation of the Convter and an additional transient field, like this:

@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;
  }

}

Depending on the conversion functions, the code could be further simplified by making them staticand importing them.

这篇关于Hibernate Envers使用@Converter和AttributeConverter失败(JPA 2.1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆