Hibernate Envers и исключение "Javassist не удалось" - PullRequest
13 голосов
/ 01 сентября 2011

Мы используем Hibernate Envers и имеем следующую ситуацию:

Класс BusinessObjectType и класс Identity со ссылкой на BusinessObjectType:

@Entity
@Table( name = "ID_IDENTITY" )
@Audited
public class Identity {

    @ManyToOne
    @JoinColumn( name = "BO_TYPE_ID" )
    @IndexColumn( name = "INDEX_BO_BO_TYPE" )
    private BusinessObjectType businessObjectType;

    […]

}

Затем мы запрашиваем все версии Identity с помощью:

AuditQuery auditQuery = auditReader.createQuery().forRevisionsOfEntity(
    Identity.class,
    false,
    true );
auditQuery.add( AuditEntity.id().eq( dbid ) );

@SuppressWarnings( "unchecked" )
List< Object[]> history = (List< Object[]>) auditQuery.getResultList();

Если сохраненный идентификатор не имеет BusinessObjectType (т. Е. businessObjectType равен нулю), все работает как шарм.

Если у идентификатора было businessObjectType != null, мы получаем исключение "Javassist Enhancement failed":

Javassist Enhancement failed: ch.ethz.id.wai.baseclasses.BusinessObjectType

Эта ошибка, по-видимому, связана с тем, что Envers пытается создать экземпляр BusinessObjectType, но я не понимаю, в чем проблема (Hibernate не имеет проблем с обоими объектами, если мы не используем AuditQuery).

Причиной исключения является

java.lang.InstantiationException: ch.ethz.id.wai.baseclasses.BusinessObjectType_$$_javassist_49

без трассировки стека.

Есть подсказка, в чем может быть проблема?

Ответы [ 2 ]

20 голосов
/ 10 сентября 2011

Это происходит внутри следующего класса JavassistLazyInitializer Прокси-инициализатор ленивого инициализатора на основе Javassist.

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

  • Отключить отложенную загрузку для отношения @ManyToOne [ Это дизайнерское решение, поэтому следите, если оно не вписывается в общее решение ]
  • Укажите значение по умолчаниюоткрытый конструктор для вашей сущности, который вызывает проблему [Это проще]
  • отключите оптимизацию отражения, если в действительности не требуется, установив для свойства hibernate.bytecode.use_reflection_optimizer значение false

Сообщите нам, еслиэто помогает

1 голос
/ 11 сентября 2011

Чтобы получить более подробную информацию об исключении, используйте средства отладки вашей IDE, чтобы установить точку останова исключения для java.lang.InstantiationException, чтобы остановить выполнение при возникновении базового исключения.Это должно показать вам полную трассировку стека и позволить вам проверить все переменные в стеке.

Если бы мне пришлось угадывать, мое первое подозрение состояло бы в том, что, поскольку связь с BusinessObjectType не отображается лениво,Обычный спящий режим никогда не пытается создать прокси для класса.Энверс в отличие от этого, кажется, делает.Прокси-сервер - это подкласс, сгенерированный во время выполнения, который переопределяет все открытые методы.Следовательно, ни класс, ни любые открытые методы (кроме тех, которые унаследованы от Object) не могут быть объявлены final, и конструктор по умолчанию должен быть доступен для подкласса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...