Hibernate Envers не работает с @Converter и AttributeConverter (JPA 2.1)

Я использую Hibernate 4.3.4 с Envers и 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)]

Теперь это не удается в таблице аудита Envers для объекта Party. Обратите внимание, что 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?


person MarcG    schedule 12.03.2014    source источник


Ответы (4)


Попробуйте использовать @Convert в Party Entity. Иногда autoApply флаг не работает

@Entity
@Audited
public class Party
    {
    @Convert(converter = NametoStringConverter.class)
    protected Name name;
    ...
    }
person shazin    schedule 13.03.2014
comment
Спасибо, шазин. Я уже тестировал это, и это не работает. Это не решило бы мою проблему, даже если бы это произошло, потому что мне нужен autoApply. Обратите внимание, что autoApply также работает, если я удалю аудит Envers. - person MarcG; 13.03.2014
comment
У нас была та же проблема (но мы не использовали Envers), и он работает с Hibernate 4.3.7. Окончательно :) ... это должно быть связано с тем, что < i> dalcorta сказал, что аннотация @Column может привести к игнорированию @Converter(autoApply = true) на AttributeConverter. - person Andreas Covidiot; 17.07.2017
comment
использование дженериков может быть другой причиной: stackoverflow.com/a/28281463/1915920 - person Andreas Covidiot; 17.07.2017
comment
К моему первому комментарию: но у нас была неиспользуемая зависимость от Envers 5.1.0.Final в другом подпроекте / pom и мы удалили ее (на самом деле было достаточно установить ее из compile scope to provided) также исправил это. - person Andreas Covidiot; 17.07.2017
comment
еще одно исправление, которое мы применили, заключалось в том, чтобы не помещать информацию о сопоставлении / аннотированные классы в отдельный проект, которые не сканируются автоматически спящим режимом: stackoverflow.com/questions/1780341/ - person Andreas Covidiot; 17.07.2017

Похоже, это известная проблема с 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 и импортировав их.

person Roland Ewald    schedule 24.08.2014
comment
Ну, на самом деле я репортер билета HHH-9042, о котором вы говорите. - person MarcG; 25.08.2014
comment
Ах я вижу. Я добавил ссылку на этот вопрос в раздел комментариев HHH-9042, чтобы мы могли обновить его здесь, когда проблема будет закрыта. Кроме того, полезно знать, что это «официальная» ошибка, которую команда Hibernate Envers считает открытой. - person Roland Ewald; 25.08.2014
comment
Сообщалось, что ошибка исправлена ​​несколько дней назад, но исправление не будет перенесено в Hibernate 4.3. Таким образом, похоже, что нам нужно либо дождаться версии 5.0, либо вернуться к типам пользователей вместо использования AttributeConvertes. - person Dario Seidl; 25.03.2015

Я вижу текст «GeneratedConstructorAccessor43» в исключении. Возможно, вам понадобится общедоступный конструктор void, чтобы JPA могла создать экземпляр NametoStringConverter.

Конструктор по умолчанию должен работать, но проверьте, есть ли у вас другой конструктор с параметрами получения или не общедоступный.

person borjab    schedule 25.03.2014
comment
Никаких других конструкторов, кроме конструктора по умолчанию, не существует. - person MarcG; 26.03.2014
comment
Извините, это было всего лишь гипотезой. Спасибо за отзыв и опубликуйте ответ, если найдете его. - person borjab; 26.03.2014
comment
Я уже сдался. Думаю, на данный момент Envers просто несовместим с AttributeConverters. - person MarcG; 27.03.2014

У меня была та же проблема, что я обнаружил, что это произошло только тогда, когда я не поместил аннотацию @Column с columnDefinition = "VARCHAR (255)" в Enum. Так что я думаю, что это лучшая работа, чем то, что есть в трекере гибернации.

person dalcorta    schedule 28.03.2016