gpt4 book ai didi

java - Hibernate 在获取实体集合后查询实体

转载 作者:太空宇宙 更新时间:2023-11-04 13:19:31 25 4
gpt4 key购买 nike

我们有以下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 实体。但我需要获取每个 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) 也没有任何效果。

最佳答案

基于https://stackoverflow.com/a/29863982/5464931 ,您可以进行另一次连接获取。

例如

"from " + StagingConcept.class.getCanonicalName() + " join fetch descriptions join fetch descriptions.concept"

但这不是最好的解决方案,因为它仍然再次查询实体/父/概念,这是不必要的。

关于java - Hibernate 在获取实体集合后查询实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33225747/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com