У меня есть простая модель, которая выглядит следующим образом (с помощью Lombok аннотаций):Как сообщить Hibernate Search индексировать поля FetchType.LAZY?
@Data
@Entity
@Indexed
public class Game {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Field(index = Index.YES, store = Store.YES)
public String name;
@Column(name="description", columnDefinition="TEXT")
@Basic(fetch = FetchType.LAZY)
@Field(index = Index.YES, store = Store.YES)
public String description;
}
Для индекса этого я написал простой общий индексатор, который выглядит следующим образом (это индексы несколько классов, следовательно, отсутствие конкретного типа):
private int index(Class<?> object, FullTextSession search_session) {
ScrollableResults results = search_session.createCriteria(object)
.setFetchSize(100)
.scroll(ScrollMode.FORWARD_ONLY);
int index = 0;
while(results.next()) {
index++;
search_session.index(results.get(0));
if (index % 10 == 0) {
search_session.flushToIndexes();
search_session.clear();
}
}
search_session.flushToIndexes();
search_session.clear();
return index;
}
Для вызова этого я просто называю это так:
FullTextSession search_session = Search.getFullTextSession(dao);
search_session.setFlushMode(FlushMode.MANUAL);
search_session.setCacheMode(CacheMode.IGNORE);
index(Game.class, search_session);
Однако в то время как т он name
работает, как и ожидалось, description
никогда не заселяется и, следовательно, никогда не индексируется. Если я удалю аннотацию @Basic(fetch = FetchType.LAZY)
от description
, тогда код работает так, как ожидалось. Чтобы обойти это, я обновил мою функцию индекса, чтобы взять конкретный тип, и теперь я вручную вызываю .getDescription()
, но есть ли более чистый способ сделать это? Какой-то способ сказать Hibernate полностью заполнить ленивые поля на .get()
?
В ответ на karim mohsen's answer я изменил мою index()
функцию, чтобы выглядеть следующим образом (главное отличие в том, что я называю Hibernate.initialize()
):
private <T> int index(Class<T> object, FullTextSession search_session) {
ScrollableResults results = search_session.createCriteria(object)
.setFetchSize(100)
.scroll(ScrollMode.FORWARD_ONLY);
int index = 0;
while(results.next()) {
index++;
T item = (T)results.get(0);
Hibernate.initialize(item);
search_session.index(item);
if (index % 10 == 0) {
search_session.flushToIndexes();
search_session.clear();
}
}
search_session.flushToIndexes();
search_session.clear();
return index;
}
Однако этот подход еще не индексировать description
поле.
Я попытался реализовать ваш ответ, однако он все еще не индексирует поле «описание». Может ли 'Hibernate.initialize' работать только с коллекциями? –
используется для принудительной инициализации прокси-сервера или постоянной коллекции, это обеспечивает только инициализацию прокси-объекта или коллекции; не гарантируется, что элементы INSIDE коллекции будут инициализированы/материализованы. См. [This] (http://www.laliluna.de/jpa-hibernate-guide/ch02s02.html) ссылка –
К сожалению, эта ссылка предполагает, что наилучшим подходом в этом случае является явно получение ленивого свойства. Я начинаю отказываться от надежды, что есть некоторая общая функция, которая будет перечислять все поля перед индексированием. –