hibernate - 休眠针对多对一关系执行的多个查询
问题描述
在处理一对多关系时,我们面临着一些奇怪的问题。为了详细描述,我们有以下实体,
RCAAssessmentUnit :-
@Entity
@Table(name = "RCAAssessmentUnit")
@Access(AccessType.FIELD)
public class RCAAssessmentUnit extends AbstractPersistentEntity implements Serializable {
private static final long serialVersionUID = -3114793801627752533L;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "document", nullable = true)
protected Document document;
@Column(name = "Name", length = 150, nullable = false)
protected String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "rca_assessment_unit_admin", nullable = true)
@NotFound(action = NotFoundAction.IGNORE)
protected RCAAssessmentUnitAdmin rcaAssessmentUnitAdmin;
RCAAssessmentUnitAdmin -
@Entity
@Table(name = "RCAAssessmentUnitAdmin")
@Access(AccessType.FIELD)
public class RCAAssessmentUnitAdmin extends AbstractPersistentEntity implements Serializable {
private static final long serialVersionUID = 8890257035008399346L;
// Name
@Column(name = "Name", length = 150, nullable = false)
protected String name;
@Column(name = "changed$")
protected Date changed;
@OneToMany(mappedBy = "rcaAssessmentUnitAdmin", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
protected List<RCAAssessmentUnit> rcaAssessmentUnits;
BCDocument 扩展 Document 并维护继承连接策略。
@Entity
@PrimaryKeyJoinColumn(name = "Document")
@Table(name = "BCDocument")
@Access(AccessType.FIELD)
public class BCDocument extends Document
------
@OneToMany(mappedBy = "document", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval = true)
@OrderBy(value = "name")
private List<RCAAssessmentUnit> rcaAssessmentUnits ;
文档 :-
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "Document", uniqueConstraints = { @UniqueConstraint(columnNames = { "Id" }) })
@Access(AccessType.FIELD)
public class Document extends AbstractPersistentEntity {
因此,有了这些关系,我们就有了一个管理模块来添加/删除/编辑“RCAAssessmentUnitAdmin”。主页首先列出了所有管理员,一旦我们尝试编辑从查询日志中添加到任何 BCDcouments 中的任何管理员,我们可以看到获取了多个查询以加载所有扩展“文档”实体的文档,例如AWT、CTT 等以及 BCDocument 例如
Hibernate: select rcaassessm0_.rca_assessment_unit_admin as ------ from RCAAssessmentUnit rcaassessm0_ where rcaassessm0_.rca_assessment_unit_admin in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select document0_.Id$ as Id1_48_0_, -----
from Document document0_ left outer join AWT document0_1_ on document0_.Id$=document0_1_.Document left outer join CTT document0_2_ on document0_.Id$=document0_2_.Document left outer join WCR document0_3_ on document0_.Id$=document0_3_.Document left outer join BRST document0_4_ on document0_.Id$=document0_4_.Document left outer join BCDocument document0_5_ on document0_.Id$=document0_5_.Document left outer join Impact_Analysis_RTO impactanal1_ on document0_.Impact_Analysis_Rto=impactanal1_.Id$ where document0_.Id$ in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
因此,第一个操作(列出所有管理员)确实保持所有关系“惰性”,但是一旦我们尝试编辑“管理员”,为什么它会尝试查询“文档”层次结构(如第二个查询所示)?在编辑它时,我们不需要文档关系或“admin”的子对象。此外,如果删除了“admin”,我们会将所有子项(RCAAssessmentUnit)的引用标记为 null,因为我们不想删除已添加到 BCDocument 中的子项。
我一直在阅读有关此问题的所有相关问答,还检查了 N+1 问题,但到目前为止无法在这里找出问题。任何建议将不胜感激。
更新: 下面是获取管理员列表的代码块。这两种方法都是支持 bean 的一部分,它是具有会话范围的接缝组件。
public void retrieve() {
TypedQuery<RCAAssessmentUnitAdmin> query = entityManager.createQuery("from RCAAssessmentUnitAdmin order by name", RCAAssessmentUnitAdmin.class);
rcaAssessmentUnitItems = query.getResultList();
}
我们有绑定此列表的 Richfaces 数据表,并且在编辑操作时,调用由下面处理。因此,即使在控件进入此编辑方法之前,在后端控制台中我也可以看到所有查询都在执行。
public void edit(RCAAssessmentUnitAdmin unitAdmin) {
log.info("edit: " + unitAdmin);
RCAAssessmentUnitAdminScreen dialog = Util.getSeamComponent (RCAAssessmentUnitAdminScreen.class, true);
dialog.setupDialog(unitAdmin, rcaAssessmentUnitItems);
}
<rich:dataTable id="items" style="word-break: keep-all;" value="#{rcaAssessmentUnitItems}" var="row" rowKeyVar="rowKey" columnClasses="col" rowClasses="odd_row, even_row">
<f:facet name="footer">
<h:outputText value="No RCA Assessment Units Found" rendered="rcaAssessmentUnitItems == null or rcaAssessmentUnitItems.size == 0}"/>
</f:facet>
<rich:column style="text-align: center; width: 70px;">
<f:facet name="header"><h:outputText value="#" /></f:facet>
<div style="width:45px !important;margin: 0 auto !important;">
<a:commandButton execute="@this" action="#{updateRCAAssessmentUnits.edit(row)}" styleClass="listItemBtn" value="#{rowKey + 1}"/>
</div>
</rich:column>
-----
</rich:dataTable>
解决方案
推荐阅读
- c# - C# - ServerCertificateValidationCallback 报告 NotSignatureValid
- python - 在 DataFrame 的开头添加 MultiIndex 汇总列
- ruby-on-rails - 为什么我需要在我的 EC2 安全组中允许“所有 TCP”才能访问我的应用程序?
- c# - 找不到 SteamVR_Controller
- python - Flask 应用程序未正确使用配置文件设置
- ios - iOS 12.0:有没有办法将 MFMailComposeViewController 导航栏标题的文本设置为白色?
- mysql - SQL:在没有主键的表中按计数过滤
- c - fgetc() 和 getc() 是否在每种情况下都会移动流指示器?
- reactjs - 有没有办法在 react-admin 中进行多次排序?
- maven-3 - 由于不推荐使用 MavenProject.getDependencyArtifacts() 如何获取直接依赖项?