2015-08-17 2 views
0

У меня есть простая модель, которая выглядит следующим образом (с помощью 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 поле.

ответ

0

Если вы отложенная загрузка коллекции нормально, но для конкретного использования, необходимо обеспечить сбор был загружен до закрытия сеанса, вы можете использовать Hibernate.initialize(Object obj)

Если вы на самом деле всегда нужны сбор загружен, вы действительно должны загрузить его с нетерпением

+0

Я попытался реализовать ваш ответ, однако он все еще не индексирует поле «описание». Может ли 'Hibernate.initialize' работать только с коллекциями? –

+0

используется для принудительной инициализации прокси-сервера или постоянной коллекции, это обеспечивает только инициализацию прокси-объекта или коллекции; не гарантируется, что элементы INSIDE коллекции будут инициализированы/материализованы. См. [This] (http://www.laliluna.de/jpa-hibernate-guide/ch02s02.html) ссылка –

+0

К сожалению, эта ссылка предполагает, что наилучшим подходом в этом случае является явно получение ленивого свойства. Я начинаю отказываться от надежды, что есть некоторая общая функция, которая будет перечислять все поля перед индексированием. –