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
и конструктор по умолчанию должен быть доступен для подкласса.