Отображение возвращает нулевые значения - PullRequest
1 голос
/ 07 июня 2019

Я хочу реализовать отображение DTO после выполнения SQL-запроса с помощью JOIN:

Запрос:

public List<Businesses> findCompaniesBusinessesById(Integer id) {
        String hql = "SELECT bus FROM " + Businesses.class.getName() + " bus " 
                + " INNER JOIN " + Companies.class.getName() + " comp "
                + " ON comp.id = bus.company_id " 
                + " WHERE bus.business_owner_id = :id "
                + " AND bus.business_owner_type = 'Merchant' "
                + " ORDER BY bus.id ASC";
        TypedQuery<Businesses> query = entityManager.createQuery(hql, Businesses.class).setParameter("id", id);
        List<Businesses> businesses = query.getResultList();
        return businesses;
    }

Организация:

@Entity
@Table(name = "businesses")
public class Businesses {

    @Id
    @Column(name = "id", unique = true, updatable = false, nullable = false)
    private int id;

    @Column(length = 4)
    private Integer business_owner_id;

    @Column(length = 255)
    private String business_owner_type;

    @Column(length = 4)
    private Integer company_id;

    @Column
    @Convert(converter = LocalDateTimeConverter.class)
    private LocalDateTime created_at;

    @Column
    @Convert(converter = LocalDateTimeConverter.class)
    private LocalDateTime updated_at;
    .......
}

! ПРИМЕЧАНИЕ! В сущности "Бизнес" у нас нет атрибута name по дизайну.

DTO:

public class BusinessesDTO {

    private Integer id;

    private String name;

    ....... 
}

! ПРИМЕЧАНИЕ! В BusDisDTO мы ожидаем name по замыслу и хотим отобразить его.

DTO Mapping:

@Mapper(config = BaseMapperConfig.class)
public interface BusinessesMapper {

    BusinessesDTO toDTO(Businesses company);
    .....
}

Результат от запроса:

enter image description here

Как видите, есть имя столбца.

Я пытался использовать этот код, чтобы получить отображение:

@Autowired
private BusinessesMapper businesses_mapper;

List<BusinessesDTO> list = null;
        try {
            list = StreamSupport.stream(merchantService.findCompaniesBusinessesById(id).spliterator(), false)
                    .map(businesses_mapper::toDTO)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            e.printStackTrace();
        }

        String joinedList = list.stream()
                  .map(BusinessesDTO::getName)
                  .collect(Collectors.joining(", "));

Но за результат я получаю NULL или NULL, NULL. По какой-то причине имя не отображается правильно, и я не могу найти, почему. Можете ли вы дать мне представление, где я не прав?

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Это не работает так, как вы его настроили. EntityManager возвращает ваши доменные объекты. Они не имеют никакой информации о том, что там, где есть другие столбцы в операторе select. Поэтому вашему картостроителю нечего получить имя.

Вам действительно нужно вернуть имя из списка. Одним из привлекательных вариантов является использование выражения конструктора для непосредственного создания DTO .

0 голосов
/ 08 июня 2019

Вы пытались использовать кортежи? Очень удобно, когда вы не хотите добавлять тонны dtos для каждого запроса

TypedQuery<Tuple> query = entityManager.createQuery(hql, Tuple.class);
List<Tuple> tuples = query.getResultList();

List<BusinessesDTO> list = new ArrayList<>();
tuples.forEach((record) ->
    {
        String name = (String) record.get("name"); 
        BusinessesDTO dto = new BusinessesDTO(name);
        list.add(dto); 
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...