我们有以下2个课程
public class StagingConcept implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "sequence")
@SequenceGenerator(name = "sequence", sequenceName = "stg_concept_seq")
@Column(name = "id")
private long id;
@Column(name = "concept_id", nullable = false, length = 18)
private String conceptId;
@OneToMany(mappedBy = "concept", fetch = FetchType.LAZY,
cascade = { CascadeType.ALL })
private Set<StagingConceptDescription> descriptions;
// rest of the class
}
public class StagingConceptDescription {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "sequence")
@SequenceGenerator(name = "sequence", sequenceName = "stg_concept_desc_seq")
@Column(name = "id")
private long id;
@ManyToOne
@JoinColumn(name = "concept_id", referencedColumnName = "concept_id")
@ForeignKey(name = "stg_concept_desc_fk1")
private StagingConcept concept;
// rest of the class
}
为了保持示例的准确性,省略了一些细节,例如其他类属性和实体注释。如果您需要更多详细信息,请告诉我。是的,从 StagingConceptDescription 到 StagingConcept 的 FK 是非 PK 外键。
当我创建一个标准时:
"from " + StagingConcept.class.getCanonicalName()
我在一个查询中从数据库中获取所有 StagingConcept 实体。但我需要descriptions
为每个 StagingConcept 获取。为此,我编写了一个查询:
"from " + StagingConcept.class.getCanonicalName() + " join fetch descriptions"
生成的 SQL 如下所示:
select stagingcon0_.id as col_0_0_,
descriptio1_.id as id178_1_,
stagingcon0_.is_active as is2_149_0_,
stagingcon0_.brand_restriction_status as brand3_149_0_,
stagingcon0_.concept_id as concept4_149_0_,
stagingcon0_.container_type as container5_149_0_,
stagingcon0_.controlled_drug_status as controlled6_149_0_,
stagingcon0_.effective_date as effective7_149_0_,
stagingcon0_.form as form149_0_,
stagingcon0_.is_multi_component as is9_149_0_,
stagingcon0_.namespace as namespace149_0_,
stagingcon0_.preferred_term as preferred11_149_0_,
stagingcon0_.source as source149_0_,
stagingcon0_.source_version as source13_149_0_,
stagingcon0_.subsidy_status as subsidy14_149_0_,
stagingcon0_.type as type149_0_,
stagingcon0_.unit_of_use_size as unit16_149_0_,
stagingcon0_.unit_of_use_size_unit as unit17_149_0_,
descriptio1_.is_active as is2_178_1_,
descriptio1_.concept_id as concept6_178_1_,
descriptio1_.is_preferred as is3_178_1_,
descriptio1_.term as term178_1_,
descriptio1_.type as type178_1_,
descriptio1_.concept_id as concept6_149_0__,
descriptio1_.id as id0__
from stg_concept stagingcon0_
inner join stg_concept_description descriptio1_ on stagingcon0_.concept_id=descriptio1_.concept_id
它确实获取了所有 StagingConcepts 及其描述,尽管该 SQL 中的结果集稍大一些。
直到这里,一切看起来都很好。但随后它又试图为每一个描述找到一个分期概念。因此,如果我有 30000 个暂存概念和 60000 个描述,它将发送另外 60000 个查询来获取每个描述的暂存概念。这看起来有点讨厌并且占用大量时间,足以超过事务超时。
为了尝试解决此问题,我将 StagingConceptDescription 更改为
public class StagingConceptDescription {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "sequence")
@SequenceGenerator(name = "sequence", sequenceName = "stg_concept_desc_seq")
@Column(name = "id")
private long id;
@ManyToOne(fetch = FetchType.LAZY, optional=false)
@JoinColumn(name = "concept_id", referencedColumnName = "concept_id")
@ForeignKey(name = "stg_concept_desc_fk1")
private StagingConcept concept;
// rest of the class
}
因此,ManyToOne 关系现在明确设置为 LAZY。而且,该关系表明该概念不是可选的,以试图表明该关系是非可选的。通过设置它,我的意思是告诉 hibernate 如果需要,创建一个代理对象应该是可以的,因为关系的另一端总是存在的。但这一切都没有任何效果。不太确定这是否可行。
我也尝试过@Fetch
注释等。它们都不起作用。即使设置为@LazyToOne(LazyToOneOption.PROXY)
没有任何效果。