【问题标题】:Is this possible: JPA/Hibernate query with list property in DTO method这可能吗:JPA/Hibernate query with list property in DTO method
【发布时间】:2021-06-29 03:03:29
【问题描述】:

在休眠中我想运行这个 JPQL / HQL 查询:

select new AppointmentDTO(a.id,a.payment)
From Appointment a
WHERE a.hospitalId = :hospitalId

约会DTO类

@Entity
public class AppointmentDTO {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Integer appointmentId;

    @OneToMany
    @JoinColumn(name = "paymentId")
    private List<Payment> payment;

    public Integer getAppointmentId() {
        return appointmentId;
    }

    public List<Payment> getPayment() {
        return payment;
    }
    public AppointmentDTO(Integer appointmentId, List<Payment> payment) {
        super();
        this.appointmentId = appointmentId;
        this.payment = payment;
    }
}

预约类

@Entity
@Table(name = "<tablename>")
public class Appointment {

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

    @OneToMany
    @JoinColumn(name = "paymentId")
    private List<Payment> payment;

//getter and setter

当我执行时,我得到这个错误:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [com.followMyDoctor.DTO.AppointmentDTO]. Expected arguments are: int, java.util.Collection [select new AppointmentDTO(a.id,a.payment) From ........ = :hospitalId]

select语句中的错误是什么,是否有可能得到预期的结果? DTO方法可以实现onetomany吗

【问题讨论】:

  • 请详细说明问题说明。
  • @krishnkantjaiswal 我需要使用 DTO 执行此查询 select new AppointmentDTO(a.id,a.payment) From Appointment a WHERE a.hospitalId = :hospitalId
  • @NikolaiShevchenko 我已经添加了整数约会ID,列出 付款

标签: java spring-boot hibernate jpa hql


【解决方案1】:

这是不可能的,因为构造函数语法仅适用于传递单数属性。如果你想这样做,你必须手动将结果集“展平”并使用流或每个循环进行分组。

我认为这是 Blaze-Persistence Entity Views 的完美用例。

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

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

@EntityView(Appointment.class)
public interface AppointmentDTO {
    @IdMapping
    Integer getAppointmentId();
    Set<PaymentDto> getPayment();

    @EntityView(Payment.class)
    interface PaymentDto {
        @IdMapping
        Integer getId();
        BigDecimal getAmount();
    }
}

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

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

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

Page<AppointmentDTO> findAll(Pageable pageable);

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

【讨论】:

    【解决方案2】:
    1. 不要在您的 DTO 类中设置任何与 Hibernate 相关的注释/映射,因为它们已经存在于您的 Entity 类中。
    2. 确保 Payment 对象在 Entity 和 DTO 类中属于同一类,如果它们不同,则属于类不匹配。

    这是您的 DTO 的理想外观:

    public class AppointmentDTO {
    
        private Integer appointmentId;
    
        private List<Payment> payment;
    
        public Integer getAppointmentId() {
            return appointmentId;
        }
    
        public List<Payment> getPayment() {
            return payment;
        }
        public AppointmentDTO(Integer appointmentId, List<Payment> payment) {
            super();
            this.appointmentId = appointmentId;
            this.payment = payment;
        }
    }
    

    此外,当在 JPQL 中使用非实体类时,请提及完整的包名以及类,如下所示:

    SELECT new com.your.package.AppointmentDTO(...) FROM ...
    

    【讨论】:

    • 是的,没关系。是否正确的 SQL 选择查询?
    • 是的,您的 JPQL 似乎是正确的,但正如我所说,只需确保实体和 DTO 类中的 Payment 类相同。在大多数此类情况下,用户定义的类都是问题。
    • 如果我删除注释错误,如“由:org.hibernate.MappingException:无法确定类型:java.util.List,在表:AppointmentDTO,列:[org.hibernate.mapping .Column(付款)] "
    • 你说的是哪个注解? DTO 中不需要注释。你能粘贴这个异常的完整堆栈跟踪吗?
    • 引起:org.hibernate.hql.internal.ast.QuerySyntaxException:无法在类 [com.followMyDoctor.DTO.AppointmentDTO] 上找到适当的构造函数。预期的参数是:int, java.util.Collection [select new AppointmentDTO(a.id,a.payment) From com.followMyDoctor.models.Appointment where a.hospitalId = :hospitalId]
    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 1970-01-01
    • 2016-03-08
    相关资源
    最近更新 更多