Поиск в гибернации с помощью ResultTransformer (DTO) - PullRequest
0 голосов
/ 26 мая 2020

Мне нужно собрать специфику c DTO из результатов поиска Hibernate, я подключил все зависимости в maven, написал следующий запрос на основе официальной документации (я удалил ненужный код, который может только сбивать с толку, оставил только то, что нужно для поиска):

public List<QuestionDto> search(String text) {

    FullTextQuery query = fullTextEntityManager.createFullTextQuery(queryBuilder
            .simpleQueryString()
            .onField("description")
            .matching(text)
            .createQuery())
            .setProjection("id", "description", "title", "countValuable", "persistDateTime", "user.fullName", "tags")
            .setResultTransformer(new ResultTransformer() {

                @Override
                public Object transformTuple(Object[] tuple, String[] aliases) {
                    return QuestionDto.builder()
                            .id(((Number) tuple[0]).longValue())
                            .title((String) tuple[2])
                            .description((String) tuple[1])
                            .countValuable(((Number) tuple[3]).intValue())
                            .persistDateTime((LocalDateTime) tuple[4])
                            .username((String) tuple[5])
                            .tags((List<TagDto>) tuple[6])
                            .build();
                }

                @Override
                public List transformList(List collection) {
                    return collection;
                }
            });
    return query.getResultList();
}

НО почему-то вместо тегов идет NULL Может у кого-то есть идеи?

Entity Question

@Indexed
public class Question {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Field(store = Store.YES)
private String title;

private Integer viewCount = 0;

@Field(store = Store.YES)
private String description;

@Field(store = Store.YES)
private LocalDateTime persistDateTime;

@Field(store = Store.YES)
private Integer countValuable = 0;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@IndexedEmbedded(includePaths = "fullName")
private User user;

@ManyToMany(fetch = FetchType.LAZY)
@IndexedEmbedded(includeEmbeddedObjectId = true, includePaths = {"name", "description"})
private List<Tag> tags;

Тег объекта

public class Tag {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Field(store = Store.YES)
private String name;

@Field(store = Store.YES)
private String description;
private LocalDateTime persistDateTime;

@ManyToMany(mappedBy = "tags", fetch = FetchType.LAZY)
@ContainedIn
private List<Question> questions;

1 Ответ

0 голосов
/ 26 мая 2020

Здесь есть две проблемы:

  1. Прогнозы на многозначные поля не поддерживаются.
  2. Вы пытаетесь проецировать на поле «объект»: «теги» делает не содержать значение само по себе, он просто имеет подполя ("tags.name", "tags.description"). Проекции на полях «объект» в настоящее время не поддерживаются.

Если вы используете бэкэнд Elasticsearch, вы можете воспользоваться преимуществом _source projection (org.hibernate.search.elasticsearch.ElasticsearchProjectionConstants#SOURCE), который вернет строковое представление документа Elasticsearch в формате JSON. Затем вы можете проанализировать его (например, с помощью Gson), чтобы извлечь любую информацию, которая вам нужна. базу данных.

Обратите внимание, что в Hibernate Search 6 (в настоящее время в бета-версии) мы собираемся добавить встроенную поддержку проекций для многозначных полей , но вряд ли это будет добавлен в Hibernate Search 5, который находится в режиме обслуживания (без новых функций или улучшений, только исправления).

В более отдаленном будущем мы, вероятно, добавим дополнительную прямую поддержку DTO .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...