使用构造函数表达式和 JPQL 使用 DTO 投影获取列表
Fetch List Using DTO projections using a Constructor Expression and JPQL
对 DisabScreenRequest 执行搜索并获取其子详细信息。使用构造函数表达式和 JPQL 使用 DTO 投影。
具有子实体的父实体 table。
@Entity
@Table(name = "SCREEN_REQUEST")
public class DisabScreenRequest implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private long requestId;
@Column(name = "CIVILID")
private Long civilId;
@ManyToMany()
@JoinTable(name = "_DISAB_SCREEN_REQ_DETAILS", joinColumns = {
@JoinColumn(name = "REQUEST_ID") }, inverseJoinColumns = { @JoinColumn(name = "DISABILTY_TYPE_ID") })
private Set<DisabMaster> disabilities = new HashSet<DisabMaster>();
public DisabScreenRequest() {
}
}
这是残疾table。
@Entity
@Table(name="DISAB_MASTER")
@Immutable
public class DisabMaster implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="DIS_TYPE_ID")
private long disabilityTypeId;
@Column(name="DIS_TYPE_DESC")
private String disTypeDesc;
public DisabMaster() {
super();
}
}
必须获取所有请求以及每个请求的残疾。
搜索 DTO(除了这里提到的以外,我还使用它添加了其他连接)。
public class RequestSearchDto {
private long requestId;
private Long civilId;
private Set<DisabMaster> disabilities;
public RequestSearchDto() {
super();
}
public RequestSearchDto(long requestId, Long civilId) {
super();
this.requestId = requestId;
this.civilId = civilId;
}
public RequestSearchDto(long requestId, Long civilId, Set<DisabMaster> disabilities) {
super();
this.requestId = requestId;
this.civilId = civilId;
this.disabilities = disabilities;
}
}
这是我的 JPQL 查询
public interface ReposJPQL {
public String GET__REQUEST = "SELECT DISTINCT new org.test.RequestSearchDto "
+ "(dsr.requestId, dsr.civilId, dsr.disabilities)"
+ " FROM DisabScreenRequest dsr WHERE 1=1 ";
}
这将获得
org.hibernate.exception.SQLGrammarException: 无法提取结果集。
我在这里做错了什么,我怎样才能获取子 table 数据?
如果您需要任何信息,请告诉我
堆栈跟踪:
Caused by: java.sql.SQLException: ORA-00936: missing expression
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:754)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:813)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1051)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:854)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1156)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3415)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3460)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60)
AFAIK,您不能使用带有 Collection
.
的构造函数表达式
参见JPA 2.2 Spec, section 4.14 BNF, read about the constructor expression:
constructor_expression ::=
NEW constructor_name ( constructor_item {, constructor_item}* )
constructor_item ::=
single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable
如果您需要获取父实体及其嵌套子实体的集合,您可以使用这种简单的方法,使用 @EntityGraph
注释或带有 join fetch
:
的 JPQL
@Entity
public class Parent {
//...
@OneToMany
private List<Child> children;
}
@Entity
public class Child {
//...
}
interface ParentRepo extends JpaRepository<Parent, Integer> {
// with @EntityGraph
@EntityGraph(attributePaths = "children")
@Override
List<Parent> findAll();
// or manually
@Query("select distinct p from Parent p left join fetch p.children")
List<Parent> findWithQuery();
}
请注意在查询中使用 distinct
以避免重复记录。
更多信息:DATAJPA-1299
这是 Blaze-Persistence Entity Views 的完美用例。
我创建了库以允许在 JPA 模型和自定义接口定义的模型之间轻松映射,类似于 Spring 类固醇的数据投影。这个想法是您按照自己喜欢的方式定义目标结构,并通过 JPQL 表达式将属性(getter)映射到实体模型。由于属性名称用作默认映射,因此您大多不需要显式映射,因为 80% 的用例都具有作为实体模型子集的 DTO。
您的模型的映射可能看起来像下面这样简单
@EntityView(DisabScreenRequest.class)
interface RequestSearchDto extends Serializable {
@IdMapping
long getRequestId();
Long getCivilId();
Set<DisabMaster> getDisabilities();
}
查询就是将实体视图应用于查询,最简单的就是通过 id 进行查询。
RequestSearchDtodto = entityViewManager.find(entityManager, RequestSearchDto.class, id);
但是 Spring 数据集成让您几乎可以像 Spring 数据投影一样使用它:https://persistence.blazebit.com/documentation/1.4/entity-view/manual/en_US/#spring-data-features
对 DisabScreenRequest 执行搜索并获取其子详细信息。使用构造函数表达式和 JPQL 使用 DTO 投影。
具有子实体的父实体 table。
@Entity
@Table(name = "SCREEN_REQUEST")
public class DisabScreenRequest implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private long requestId;
@Column(name = "CIVILID")
private Long civilId;
@ManyToMany()
@JoinTable(name = "_DISAB_SCREEN_REQ_DETAILS", joinColumns = {
@JoinColumn(name = "REQUEST_ID") }, inverseJoinColumns = { @JoinColumn(name = "DISABILTY_TYPE_ID") })
private Set<DisabMaster> disabilities = new HashSet<DisabMaster>();
public DisabScreenRequest() {
}
}
这是残疾table。
@Entity
@Table(name="DISAB_MASTER")
@Immutable
public class DisabMaster implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="DIS_TYPE_ID")
private long disabilityTypeId;
@Column(name="DIS_TYPE_DESC")
private String disTypeDesc;
public DisabMaster() {
super();
}
}
必须获取所有请求以及每个请求的残疾。
搜索 DTO(除了这里提到的以外,我还使用它添加了其他连接)。
public class RequestSearchDto {
private long requestId;
private Long civilId;
private Set<DisabMaster> disabilities;
public RequestSearchDto() {
super();
}
public RequestSearchDto(long requestId, Long civilId) {
super();
this.requestId = requestId;
this.civilId = civilId;
}
public RequestSearchDto(long requestId, Long civilId, Set<DisabMaster> disabilities) {
super();
this.requestId = requestId;
this.civilId = civilId;
this.disabilities = disabilities;
}
}
这是我的 JPQL 查询
public interface ReposJPQL {
public String GET__REQUEST = "SELECT DISTINCT new org.test.RequestSearchDto "
+ "(dsr.requestId, dsr.civilId, dsr.disabilities)"
+ " FROM DisabScreenRequest dsr WHERE 1=1 ";
}
这将获得 org.hibernate.exception.SQLGrammarException: 无法提取结果集。
我在这里做错了什么,我怎样才能获取子 table 数据? 如果您需要任何信息,请告诉我
堆栈跟踪:
Caused by: java.sql.SQLException: ORA-00936: missing expression
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:754)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:813)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1051)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:854)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1156)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3415)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3460)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60)
AFAIK,您不能使用带有 Collection
.
参见JPA 2.2 Spec, section 4.14 BNF, read about the constructor expression:
constructor_expression ::=
NEW constructor_name ( constructor_item {, constructor_item}* )
constructor_item ::=
single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable
如果您需要获取父实体及其嵌套子实体的集合,您可以使用这种简单的方法,使用 @EntityGraph
注释或带有 join fetch
:
@Entity
public class Parent {
//...
@OneToMany
private List<Child> children;
}
@Entity
public class Child {
//...
}
interface ParentRepo extends JpaRepository<Parent, Integer> {
// with @EntityGraph
@EntityGraph(attributePaths = "children")
@Override
List<Parent> findAll();
// or manually
@Query("select distinct p from Parent p left join fetch p.children")
List<Parent> findWithQuery();
}
请注意在查询中使用 distinct
以避免重复记录。
更多信息:DATAJPA-1299
这是 Blaze-Persistence Entity Views 的完美用例。
我创建了库以允许在 JPA 模型和自定义接口定义的模型之间轻松映射,类似于 Spring 类固醇的数据投影。这个想法是您按照自己喜欢的方式定义目标结构,并通过 JPQL 表达式将属性(getter)映射到实体模型。由于属性名称用作默认映射,因此您大多不需要显式映射,因为 80% 的用例都具有作为实体模型子集的 DTO。
您的模型的映射可能看起来像下面这样简单
@EntityView(DisabScreenRequest.class)
interface RequestSearchDto extends Serializable {
@IdMapping
long getRequestId();
Long getCivilId();
Set<DisabMaster> getDisabilities();
}
查询就是将实体视图应用于查询,最简单的就是通过 id 进行查询。
RequestSearchDtodto = entityViewManager.find(entityManager, RequestSearchDto.class, id);
但是 Spring 数据集成让您几乎可以像 Spring 数据投影一样使用它:https://persistence.blazebit.com/documentation/1.4/entity-view/manual/en_US/#spring-data-features