Hibernate Envers и исключение "Javassist не удалось"

Мы используем 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 ответа

Решение

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

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

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

Дайте нам знать, если это поможет

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

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

Другие вопросы по тегам