Java Hibernate/JPA映射响应-子查询

Java Hibernate/JPA映射响应-子查询,java,spring-boot,hibernate,spring-data-jpa,Java,Spring Boot,Hibernate,Spring Data Jpa,我正试图通过一个自定义生成调用获取所有数据。我使用的是Spring Boot版本2.3.8。 我的问题是,我想在存储库中的select语句上获得一个带有子查询的字符串列表 下面是“TestMapper”的示例,其中包含我想要映射的数据 private String location; private Date checkoutRequestAt; private Date checkoutAt; private List<String> macAddressList; private

我正试图通过一个自定义生成调用获取所有数据。我使用的是Spring Boot版本2.3.8。 我的问题是,我想在存储库中的select语句上获得一个带有子查询的字符串列表

下面是“TestMapper”的示例,其中包含我想要映射的数据

private String location;
private Date checkoutRequestAt;
private Date checkoutAt;
private List<String> macAddressList;
private Boolean checkout;
请注意,子查询应返回多于1个结果。列表对象是正确的

当我启动应用程序时,会出现以下异常。。 我更确信我以错误的方式执行select语句。也许有人有这样的例子

Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [test.jpa.TestMapper]. Expected arguments are: java.lang.String, java.util.Date, java.util.Date, java.lang.String, boolean [select new test.jpa.TestMapper(l.name,l.checkoutRequestAt,l.checkoutAt,(select d.macAddress from test.jpa.Device d where d.location = l),l.checkout) from test.jpa.Location l where l.name = :locationName]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:725)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)
at com.sun.proxy.$Proxy171.createQuery(Unknown Source)
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87)
顺便说一下,如果我将列表类型更改为Object,我可以启动spring启动项目,但我会得到一个异常,即我的select device查询返回的结果多于1个。多个结果是预期的,因为我可以有多个设备分配到一个位置


谢谢你

我不认为JPA有能力在子选择中选择一个事物列表

因此,我将切换到使用带有
ResultSetExtractor
JdbcTemplate
。 后者允许从结果集的多行构建一个结果对象

如果使用SQL语句将subselect替换为联接,这应该可以正常工作

选择
l、 名字,
l、 签出请求,
l、 退房,
d、 macAddress,
l、 结帐“+
从位置l
连接设备d
在d.locationId=l.id上
其中l.name=:locationName

使用JPA可能会有类似的功能,但我不认为使用JPA有什么好处。

使用普通JPA是不可能的。尽管如此,我认为这是一个完美的JPA用例

我创建了这个库,以便在JPA模型和自定义接口或抽象类定义的模型之间进行简单的映射,类似于类固醇上的Spring数据投影。其思想是以您喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(getter)映射到实体模型

在Blaze持久性实体视图中,您的用例的DTO模型可能如下所示:

@EntityView(Location.class)
public interface TestMapper {
    @IdMapping("name")
    String getLocationName();
    Date getCheckoutRequestAt();
    Date getCheckoutAt();
    @Mapping("Device[locationId = VIEW(id)]")
    List<String> getMacAddressList();
    Boolean getCheckout();
}

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

最终得到了相同的解决方案,但您的解决方案更加清晰。感谢您的建议,这是一个新的经验。
@EntityView(Location.class)
public interface TestMapper {
    @IdMapping("name")
    String getLocationName();
    Date getCheckoutRequestAt();
    Date getCheckoutAt();
    @Mapping("Device[locationId = VIEW(id)]")
    List<String> getMacAddressList();
    Boolean getCheckout();
}
Page<TestMapper> findAll(Pageable pageable);