Получение TransientObjectException при создании моего начального индекса

Я использую следующий код для инициализации моего поискового индекса Hibernate:

EntityManager em = ...
FullTextEntityManager fullTextEM = Search.getFullTextEntityManager(em);
fullTextEM.createIndexer().startAndWait();

Теперь, когда я выполняю этот код, я получаю следующее исключение:

ERROR: HSEARCH000058: HSEARCH000116: Unexpected error during MassIndexer operation
org.hibernate.TransientObjectException: cannot lock an unsaved transient instance: com.example.hs.model.Division
at org.hibernate.event.internal.DefaultLockEventListener.onLock(DefaultLockEventListener.java:75)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:724)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:717)
at org.hibernate.internal.SessionImpl.access$1700(SessionImpl.java:170)
at org.hibernate.internal.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2276)
at org.hibernate.search.batchindexing.impl.EntityConsumerLuceneWorkProducer.indexAllQueue(EntityConsumerLuceneWorkProducer.java:130)
at org.hibernate.search.batchindexing.impl.EntityConsumerLuceneWorkProducer.run(EntityConsumerLuceneWorkProducer.java:102)
at org.hibernate.search.batchindexing.impl.OptionallyWrapInJTATransaction.run(OptionallyWrapInJTATransaction.java:112)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)

В этом случае класс com.example.hs.model.Division имеет две аннотации @Transient для методов, вычисляющих возвращаемое значение из HashMap. HashMap извлекается через Hibernate следующим образом:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "division_id", referencedColumnName = "id")
@MapKey(name = "language")
@Field(name="name")
@FieldBridge(impl = com.example.hs.search.LanguageDivisionTextBridge.class)
protected Map<Language, DivisionText> getDivisionTextMap() {
    return divisionTextMap;
}

Как видите, я использую пользовательский FieldBridge, чтобы помочь в отображении. Класс DivisionText также отмечен аннотацией @Indexed и успешно индексируется.

Полный набор исходников можно найти по адресу:

https://github.com/jsvazic/hibernate-search-example

Любая помощь будет принята с благодарностью.


person John S    schedule 05.04.2012    source источник


Ответы (1)


Ваша проблема связана не с аннотацией @Transient внутри Foo,, а с Foo в целом. Некоторый код внутри процедуры индексации пытается вызвать Session.lock(foo),, но в то время, когда foo все еще является простым объектом, прежде чем он был назначен сеансу с использованием Session.save или Session.persist. Возможно, было бы полезно добавить параметр cascade=PERSIST в аннотацию к полю foo в вашем родительском объекте, как объяснено здесь.

person Marko Topolnik    schedule 06.04.2012
comment
Я говорил слишком рано. Кажется, что проблема все еще существует. У меня есть ухо одного из команды Hibernate Search, поэтому я надеюсь, что они могут помочь. Пример кода можно найти по адресу https://github.com/jsvazic/hibernate-search-example< /а> - person John S; 10.04.2012
comment
Просто быстрое обновление, но я изменил пример кода, чтобы он стал намного проще. Кажется, проблема именно в классе Division, так как DivisionText работает нормально, т. е. когда я добавляю аннотацию @Indexed в Division, происходит сбой. - person John S; 12.04.2012
comment
А где в вашем примере com.example.Foo? Теперь, когда у вас есть этот пример кода, обновите свой вопрос, чтобы отразить его. - person Marko Topolnik; 12.04.2012
comment
Хороший вопрос, извините за это. Вопрос был обновлен, чтобы отразить пример кода и более простой случай. - person John S; 12.04.2012
comment
Итак, давайте посмотрим, что вы сделали... почему у вас нет cascade=PERSIST (или ALL) на DivisionText.division? - person Marko Topolnik; 12.04.2012
comment
Упущение с моей стороны, но я пытался добавить его без успеха. Я обновлю GitHub соответственно. - person John S; 12.04.2012
comment
Я понял, что индексация на самом деле ничего не записывает в БД, она просто читает. Поэтому, если он пытается заблокировать временный экземпляр, этот экземпляр вышел из Hibernate в постоянном состоянии, а затем был исключен, вероятно, в session.close(), и после этого какой-то код пытается его заблокировать. - person Marko Topolnik; 12.04.2012
comment
Я просмотрел код EntityConsumerLuceneworkProducer, это чертовски грязно. - person Marko Topolnik; 12.04.2012
comment
Они только что выпустили новую версию поиска Hibernate (4.1). Я использовал 4.0, поэтому я не уверен, какую версию кода вы смотрели. Подозреваю, что все-таки сумбурно, но все же. - person John S; 12.04.2012
comment
Если вы нажмете на ссылку под названием класса в моем предыдущем комментарии, то сами все увидите. - person Marko Topolnik; 12.04.2012
comment
Спасибо за помощь, Марко. Я отмечу, что это принято, так как я ничего не получаю с этим. Никто на форумах Hibernate тоже не помогает. Я ценю помощь, но мы решили вместо этого использовать операторы LIKE. - person John S; 23.04.2012
comment
Если вам когда-нибудь понадобится вернуться к Lucene, мой сердечный совет — пропустить все остальное и использовать Lucene напрямую, самостоятельно написав весь необходимый код. Lucene — фантастическая библиотека, не имеющая себе равных по качеству ни с чем в экосистеме Lucene. Вы окажете себе большую услугу, если вложите средства в изучение Lucene API. - person Marko Topolnik; 23.04.2012