【问题标题】:Mapping is returning null values映射返回空值
【发布时间】:2019-10-22 11:12:43
【问题描述】:

我想在使用 JOIN 执行 SQL 查询后实现 DTO 映射:

查询:

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;

    ....... 
}

!注意! 在 BusinessesDTO 中,我们期望 name 在设计上,我们想要映射它。

DTO 映射:

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

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

查询结果:

如您所见,有一个列名。

我尝试使用此代码来获取映射:

@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。由于某种原因,名称未正确映射,我找不到原因。你能告诉我我哪里错了吗?

【问题讨论】:

  • 没有足够的信息来回答这个问题。我不明白问题出在哪里:merchantService.findCompaniesBusinessesById(id) 正在返回正确的值?如果不是,您应该在问题中添加休眠的映射配置。如果可行,您应该在问题中添加businesss_mapper::toDTO 实施。
  • @Sodala 请查看更新后的帖子。
  • 我不明白。您的实体中没有名称,并且您想要映射一个在您的 dto 中不存在的字段。只需将其添加到您的实体中即可。
  • @Sodala 是的。是否可以在不将其添加到实体中的情况下实现这一点?
  • 只是为了纠正你我的实体中没有名称,我想映射一个确实存在于 dto 中的字段。

标签: java sql jpa spring-data-jpa


【解决方案1】:

这在您设置它时根本不起作用。 EntityManager 返回您的域对象。 这些没有任何信息,以至于 select 语句中的其他列在哪里。 因此,您的映射器没有什么可以从中获得名称的。

您需要从选择中实际返回名称。 一个有吸引力的选择是使用constructor expression to create the DTO directly

【讨论】:

  • 你能告诉我如何从选择中返回名称吗?
  • 看看链接。如果您对此有疑问,请针对您面临的具体问题提出一个新问题。
【解决方案2】:

您是否尝试过使用元组?当您不想为每个查询添加大量 dto 时非常方便

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); 
    });

【讨论】:

  • 不,它会得到名字吗?
  • 试试看。该查询返回查询在元组列表中返回的任何内容。如果你愿意,你也可以得到一个索引值
猜你喜欢
  • 2019-01-05
  • 2015-04-05
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多