hibernate - 当孩子为空时,JPA LEFT JOIN FETCH 导致多个选择语句
问题描述
这是我的查询:
@Query("SELECT DISTINCT f FROM FlowNlp f LEFT JOIN FETCH f.flowSelection fs JOIN FETCH f.chatConversations cc " +
"WHERE f.initialFlowTriggered IN( SELECT DISTINCT fd.name FROM FlowDefinition fd, FlowPermission fp WHERE fp.flowName = fd.name " +
") AND cc.flowStep = 'Run NLP'" +
"AND f.created BETWEEN :start AND :end")
List<FlowNlp> getFlowNlpBetween(@Param("start") Date start, @Param("end") Date end);
这里是实体:
FlowNlp.java
@Entity
@Table(name = "flow_nlp")
@Data
@TypeDef(name = "json", typeClass = JsonStringType.class)
@NoArgsConstructor
public class FlowNlp implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "PK")
private int id;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "FLOW_SELECTION_KEY", referencedColumnName = "FLOW_SELECTION_KEY")
@NotFound(action = NotFoundAction.IGNORE)
private List<ChatConversation> chatConversations;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FLOW_SELECTION_KEY")
@NotFound(action = NotFoundAction.IGNORE)
private FlowSelection flowSelection;
@Column(name = "NLP_TYPE")
private String nlpType;
@Column(name = "FLOW_MATCH_JSON")
@Type(type = "json")
private Object flowMatchJson;
@Column(name = "MATCH_DESCRIPTION")
private String matchDescription;
@Column(name = "INITIAL_FLOW_TRIGGERED")
private String initialFlowTriggered;
@Column(name = "JOB_ID")
private String jobId;
@Column(name = "IS_USED")
private Boolean isUsed;
@Column(name = "IS_TAUGHT")
private Boolean isTaught;
@Column(name = "IS_PRIMARY")
private Boolean isPrimary;
@Column(name = "CREATETS")
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Column(name = "MODIFYTS")
@Temporal(TemporalType.TIMESTAMP)
private Date modified;
}
聊天对话.java
@Entity
@Table(name = "chat_conversation")
@Data
public class ChatConversation implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "CHAT_CONVERSATION_PK")
private int id;
@Column(name = "FLOW_SELECTION_KEY")
private String flowSelectionKey;
@Column(name = "CHATTING_USER")
private String chattingUser;
@Column(name = "CHATTING_USERTYPE")
private String chattingUserType;
@Column(name = "BOT")
private String bot;
@Column(name = "CHAT_CLIENT")
private String chatClient;
@Column(name = "PHRASE")
private String phrase;
@Column(name = "FLOW_STEP")
private String flowStep;
@Column(name = "JOB_ID")
private String jobId;
@Column(name = "INBOUND")
private Boolean inbound;
@Column(name = "UU_RESPONSE_DELTA")
private String uuResponseDelta;
@Column(name = "UB_RESPONSE_DELTA")
private String ubResponseDelta;
@Column(name = "THREAD_LOCK")
private String threadLock;
@Column(name = "CREATETS")
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Column(name = "MODIFYTS")
@Temporal(TemporalType.TIMESTAMP)
private Date modified;
}
FlowSelection.java
@Entity
@Table(name = "flow_selection")
@Data
public class FlowSelection {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "FLOW_SELECTION_KEY")
private String id;
@Column(name = "FINAL_SELECTED_FLOW")
private String finalSelectedFlow;
@Column(name = "FINAL_SELECTED_DESCRIPTION")
private String finalSelectedDescription;
@Column(name = "CREATETS")
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Column(name = "MODIFYTS")
@Temporal(TemporalType.TIMESTAMP)
private Date modified;
}
每当 FlowNlp 结果没有 FlowSelection 时,Hibernate 似乎对 FlowSelection 表执行了 5 个以上相同的查询:
2020-02-04 15:19:01.808 DEBUG 56820 --- [nio-8081-exec-1] org.hibernate.SQL : select flowselect0_.flow_selection_key as flow_sel1_12_0_, flowselect0_.createts as createts2_12_0_, flowselect0_.final_selected_description as final_se3_12_0_, flowselect0_.final_selected_flow as final_se4_12_0_, flowselect0_.modifyts as modifyts5_12_0_ from flow_selection flowselect0_ where flowselect0_.flow_selection_key=?
2020-02-04 15:19:01.810 TRACE 56820 --- [nio-8081-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [1580844097880_TK82506_e6b17201db3acc14eab2fcfaae961914]
2020-02-04 15:19:01.859 DEBUG 56820 --- [nio-8081-exec-1] org.hibernate.SQL : select flowselect0_.flow_selection_key as flow_sel1_12_0_, flowselect0_.createts as createts2_12_0_, flowselect0_.final_selected_description as final_se3_12_0_, flowselect0_.final_selected_flow as final_se4_12_0_, flowselect0_.modifyts as modifyts5_12_0_ from flow_selection flowselect0_ where flowselect0_.flow_selection_key=?
2020-02-04 15:19:01.859 TRACE 56820 --- [nio-8081-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [1580844097880_TK82506_e6b17201db3acc14eab2fcfaae961914]
2020-02-04 15:19:01.892 DEBUG 56820 --- [nio-8081-exec-1] org.hibernate.SQL : select flowselect0_.flow_selection_key as flow_sel1_12_0_, flowselect0_.createts as createts2_12_0_, flowselect0_.final_selected_description as final_se3_12_0_, flowselect0_.final_selected_flow as final_se4_12_0_, flowselect0_.modifyts as modifyts5_12_0_ from flow_selection flowselect0_ where flowselect0_.flow_selection_key=?
2020-02-04 15:19:01.893 TRACE 56820 --- [nio-8081-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [1580844097880_TK82506_e6b17201db3acc14eab2fcfaae961914]
2020-02-04 15:19:01.920 DEBUG 56820 --- [nio-8081-exec-1] org.hibernate.SQL : select flowselect0_.flow_selection_key as flow_sel1_12_0_, flowselect0_.createts as createts2_12_0_, flowselect0_.final_selected_description as final_se3_12_0_, flowselect0_.final_selected_flow as final_se4_12_0_, flowselect0_.modifyts as modifyts5_12_0_ from flow_selection flowselect0_ where flowselect0_.flow_selection_key=?
2020-02-04 15:19:01.920 TRACE 56820 --- [nio-8081-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [1580844097880_TK82506_e6b17201db3acc14eab2fcfaae961914]
2020-02-04 15:19:01.950 DEBUG 56820 --- [nio-8081-exec-1] org.hibernate.SQL : select flowselect0_.flow_selection_key as flow_sel1_12_0_, flowselect0_.createts as createts2_12_0_, flowselect0_.final_selected_description as final_se3_12_0_, flowselect0_.final_selected_flow as final_se4_12_0_, flowselect0_.modifyts as modifyts5_12_0_ from flow_selection flowselect0_ where flowselect0_.flow_selection_key=?
2020-02-04 15:19:01.950 TRACE 56820 --- [nio-8081-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [1580844097880_TK82506_e6b17201db3acc14eab2fcfaae961914]
当返回许多没有 FlowSelection 的行时,这会导致希望查询的时间更长。
我试过只是做一个正常的JOIN FETCH
,但不再返回其中有一个空 FlowSelection 的行。我该怎么做才能得到与我得到的结果相同但没有所有额外(不必要的?)查询的结果?
解决方案
推荐阅读
- hadoop - 启动 hbase 失败
- abp - 如何在 ABP 框架中将多租户与 Blazor 应用程序一起使用
- python-3.x - 什么是刷新令牌以及如何、在哪里使用它?
- mongodb - 聚合 $group 以了解集合中的上一个和下一个文档
- rcpp - 使用 Rcpp 安装 R 包时的警告
- f# - 将有限坐标表示为 F# 类型
- python - 如何生成随机的 16 字符十六进制字符串,然后在 python 中使用破折号 (-) 除以 4?
- javascript - 在 html 中嵌入本地 asciinema 文件
- java - 如何从两个创建一个新数组并根据原始数组中的值初始化新数组
- keycloak - 在 Keycloak 中没有为孩子错误找到 publicKey 是什么意思