1

我们有以下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)没有任何效果。

4

1 回答 1

0

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

例如

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

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

于 2015-10-25T21:52:01.873 回答