【问题标题】:How to use JPQL for fetching DTO objects如何使用 JPQL 获取 DTO 对象
【发布时间】:2021-10-28 12:09:50
【问题描述】:

我最近了解了 dto,所以在我的应用程序中,我尝试使用 JPQL 查询获取 DTO,但我得到了异常。

这是我的代码:

public class Teacher {

@ElementCollection
@CollectionTable(name = "teacher_phone_number",
        joinColumns = {@JoinColumn(name = "teacher_id")})
@Column(name = "phone_number")
private Set<String> phoneNumbers;

// getter setters
}


public class TeacherDTO {
private long id;

private String teacherName;

private Set<String> phoneNumber;

public TeacherDTO(long id, String teacherName, Set<String> phoneNumber) {
    this.id = id;
    this.teacherName = teacherName;
    this.phoneNumber = phoneNumber;
}

//Setter getters
}


public class TeacherRepositoryImpl {

@Override
public TeacherDTO fetchTeacherDTOById(Long id) {

    return entityManager.createQuery("select new service.dto.TeacherDTO(t.id, 
concat(t.firstName, ' ', t.lastName)" + ", tp.phoneNumbers) 
from Teacher t join t.phoneNumbers tp where 
    t.id = :id", TeacherDTO.class).setParameter("id", id).getSingleResult();
}

}

伙计们,我想将 DTO 添加到我的服务层,所以我不得不使用 JPQL 来获取 dto 实体。但我得到这个错误:

Exception in thread "main" java.lang.IllegalArgumentException: 
org.hibernate.QueryException: cannot dereference scalar collection 
element: phoneNumbers [select new service.dto.TeacherDTO(t.id, 
concat(t.firstName, ' ', t.lastName), tp.phoneNumbers) from 
model.Teacher t join t.phoneNumbers tp where t.id = :id]

提前致谢!

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    由于 JPA 构造器语法不支持“聚合”,因此无法直接传递这样的集合,但我认为这是 Blaze-Persistence Entity Views 的完美用例。

    我创建了该库以允许在 JPA 模型和自定义接口或抽象类定义模型之间轻松映射,例如 Spring Data Projections on steroids。这个想法是您按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

    使用 Blaze-Persistence Entity-Views 的用例的 DTO 模型可能如下所示:

    @EntityView(Teacher.class)
    public interface TeacherDTO {
        @IdMapping
        Long getId();
        String getTeacherName();
        Set<String> getPhoneNumbers();
    }
    

    查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

    TeacherDTO a = entityViewManager.find(entityManager, TeacherDTO.class, id);

    Spring Data 集成让您可以像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

    Page<TeacherDTO> findAll(Pageable pageable);
    

    最好的部分是,它只会获取实际需要的状态!

    【讨论】:

      【解决方案2】:

      不确定您要实现什么,但最好从数据库中获取元素作为实体,然后稍后使用 Java 的 ModelMapper 之类的东西将它们转换为 DTO。看一些例子here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-05
        • 2018-12-27
        • 2023-02-05
        • 1970-01-01
        • 1970-01-01
        • 2016-09-24
        • 2010-12-12
        • 2023-01-16
        相关资源
        最近更新 更多