当前位置: 首页 > 知识库问答 >
问题:

为什么hibernate在id上搜索时使用JOIN,而不是在另一个字段上?

索曾琪
2023-03-14

我目前使用Spring Data和存储库来获取我的数据。当使用默认值时:

myRepo.findById(id)

生成一个使用联接的查询:

Hibernate: select questionna0_.id as id1_6_0_, questionna0_.action as action2_6_0_, questionna0_.first_question_id as first_qu3_6_0_, answers1_.questionnaire_id as question5_0_1_, answers1_.id as id1_0_1_, answers1_.id as id1_0_2_, answers1_.order as order2_0_2_, answers1_.question_id as question3_0_2_, answers1_.value as value4_0_2_, validation2_.answer_id as answer_i2_1_3_, validation2_.id as id1_1_3_, validation2_.id as id1_1_4_, validation2_.answer_id as answer_i2_1_4_, validation2_.operator as operator3_1_4_, validation2_.value as value4_1_4_, questions3_.questionnaire_id as question7_5_5_, questions3_.id as id1_5_5_, questions3_.id as id1_5_6_, questions3_.answer_type as answer_t2_5_6_, questions3_.optional as optional3_5_6_, questions3_.question_key as question4_5_6_, questions3_.question_label as question5_5_6_, questions3_.question_type as question6_5_6_, answers4_.question_id as question3_0_7_, answers4_.id as id1_0_7_, answers4_.id as id1_0_8_, answers4_.order as order2_0_8_, answers4_.question_id as question3_0_8_, answers4_.value as value4_0_8_, branches5_.question_id as question3_2_9_, branches5_.id as id1_2_9_, branches5_.id as id1_2_10_, branches5_.question_id_target as question2_2_10_, conditions6_.branch_id as branch_i5_3_11_, conditions6_.id as id1_3_11_, conditions6_.id as id1_3_12_, conditions6_.operator as operator2_3_12_, conditions6_.question_id as question3_3_12_, conditions6_.value as value4_3_12_ from questionnaire questionna0_ left outer join answer answers1_ on questionna0_.id=answers1_.questionnaire_id left outer join answer_validation validation2_ on answers1_.id=validation2_.answer_id left outer join question questions3_ on questionna0_.id=questions3_.questionnaire_id left outer join answer answers4_ on questions3_.id=answers4_.question_id left outer join branch branches5_ on questions3_.id=branches5_.question_id left outer join branch_condition conditions6_ on branches5_.id=conditions6_.branch_id where questionna0_.id=?

但是,当使用同一个存储库对另一个字段进行查询时,要执行几乎相同的操作:

myRepo.findByAction(action)
Hibernate: select questionna0_.id as id1_6_, questionna0_.action as action2_6_, questionna0_.first_question_id as first_qu3_6_ from questionnaire questionna0_ where questionna0_.action=?
Hibernate: select questions0_.questionnaire_id as question7_5_0_, questions0_.id as id1_5_0_, questions0_.id as id1_5_1_, questions0_.answer_type as answer_t2_5_1_, questions0_.optional as optional3_5_1_, questions0_.question_key as question4_5_1_, questions0_.question_label as question5_5_1_, questions0_.question_type as question6_5_1_ from question questions0_ where questions0_.questionnaire_id=?
Hibernate: select answers0_.question_id as question3_0_0_, answers0_.id as id1_0_0_, answers0_.id as id1_0_1_, answers0_.order as order2_0_1_, answers0_.question_id as question3_0_1_, answers0_.value as value4_0_1_ from answer answers0_ where answers0_.question_id=?
Hibernate: select validation0_.answer_id as answer_i2_1_0_, validation0_.id as id1_1_0_, validation0_.id as id1_1_1_, validation0_.answer_id as answer_i2_1_1_, validation0_.operator as operator3_1_1_, validation0_.value as value4_1_1_ from answer_validation validation0_ where validation0_.answer_id=?
Hibernate: select branches0_.question_id as question3_2_0_, branches0_.id as id1_2_0_, branches0_.id as id1_2_1_, branches0_.question_id_target as question2_2_1_ from branch branches0_ where branches0_.question_id=?
Hibernate: select conditions0_.branch_id as branch_i5_3_0_, conditions0_.id as id1_3_0_, conditions0_.id as id1_3_1_, conditions0_.operator as operator2_3_1_, conditions0_.question_id as question3_3_1_, conditions0_.value as value4_3_1_ from branch_condition conditions0_ where conditions0_.branch_id=?
Hibernate: select answers0_.question_id as question3_0_0_, answers0_.id as id1_0_0_, answers0_.id as id1_0_1_, answers0_.order as order2_0_1_, answers0_.question_id as question3_0_1_, answers0_.value as value4_0_1_ from answer answers0_ where answers0_.question_id=?
Hibernate: select validation0_.answer_id as answer_i2_1_0_, validation0_.id as id1_1_0_, validation0_.id as id1_1_1_, validation0_.answer_id as answer_i2_1_1_, validation0_.operator as operator3_1_1_, validation0_.value as value4_1_1_ from answer_validation validation0_ where validation0_.answer_id=?
Hibernate: select branches0_.question_id as question3_2_0_, branches0_.id as id1_2_0_, branches0_.id as id1_2_1_, branches0_.question_id_target as question2_2_1_ from branch branches0_ where branches0_.question_id=?
Hibernate: select answers0_.questionnaire_id as question5_0_0_, answers0_.id as id1_0_0_, answers0_.id as id1_0_1_, answers0_.order as order2_0_1_, answers0_.question_id as question3_0_1_, answers0_.value as value4_0_1_ from answer answers0_ where answers0_.questionnaire_id=?
@Entity
@Table(name = "questionnaire")
data class QuestionnaireEntity(
    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    val id: UUID?,
    val action: String,
    val firstQuestionId: UUID?,
    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "questionnaireId")
    val questions: Set<QuestionEntity>,
    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "questionnaireId")
    val answers: Set<AnswerEntity>
)
@Entity
@Table(name = "question")
data class QuestionEntity(
    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    val id: UUID?,
    val optional: Boolean,
    val questionLabel: String?,
    val questionKey: String?,
    @Enumerated(EnumType.STRING)
    val questionType: QuestionType,
    @Enumerated(EnumType.STRING)
    val answerType: AnswerType,
    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "questionId")
    val answers: Set<AnswerEntity>,
    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "questionId")
    val branches: Set<BranchEntity>
)
@Entity
@Table(name = "answer")
@TypeDefs(
    TypeDef(name = "jsonb", typeClass = JsonBinaryType::class)
)
data class AnswerEntity(
    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    val id: UUID?,
    val questionId: UUID,
    @Type(type = "jsonb")
    val value: Map<String, Any>?,
    val order: Int,
    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "answerId")
    val validations: Set<AnswerValidationEntity>
)

共有1个答案

史英睿
2023-03-14

这些方法行为不同的原因是因为它们的实现非常不同。

FindByID是使用EntityManager.find实现的。这是可能的,因为它只在SimpleJParepository中实现了一次,它实现了CrudRepository的方法。EntityManager.find反过来支持实体上的惰性/热切配置。

当使用某种形式的查询时,该配置被忽略,这正是添加到存储库中的其他findby...方法所发生的情况。您可以用@entitygraph注释它们,以证明一个实体图,指定您希望它使用的获取策略。

 类似资料:
  • 问题内容: 我不确定他们已经进行了多长时间,但是我只是注意到Google 在他们的搜索网址中使用 # 而不是 搜索? 。 新方法 http://www.google.com/#q=stackoverflow 旧方法 http://www.google.com/search?q=stackoverflow 井号/井号通常用作页面部分的锚点。 除了较短的网址,对Google有什么好处?它似乎违背了搜索

  • 我知道容器可以有其他参数,如填充或装饰,但如果我不使用这些,为什么我要使用SizedBox而不是容器? 它们之间存在性能差异?

  • 问题内容: 我正在使用ColdFusion 8和SQL Server 2008 R2。 我试图查询一列值以获取具有范围内的值的行。该列应为数字,但不是。它被设置为varchar(由其他人)。有100,000多行数据。这是数据的伪样本: 我的查询如下所示: 该查询不会运行,因为where语句的列是varchar,并且出现转换错误,因此我必须将where语句更改为此: 现在,当我运行这样的查询时,它会

  • 我有一个blob字段,当我保存表中的其他字段时,它不希望被更新。尽管我已经将该字段指定为updatable=false,Hibernate似乎正在进行areEqual检查。因为该字段是延迟加载的,所以它是null,当它在保存时进行areEqual检查时,我得到了一个ClassCastException。当它不可更新时,为什么要在那个字段上进行比较? 因此,我的字段被指定为: 在org.spring

  • 问题内容: 似乎要合并两个或多个表,我们可以使用join或where。一个相对于另一个的优点是什么? 问题答案: 任何涉及多个表的查询都需要某种形式的关联,以将结果从表“ A”链接到表“ B”。传统的(ANSI-89)方法是: 在FROM子句中列出逗号分隔列表中涉及的表 在WHERE子句中编写表之间的关联 FROM TABLE_A a, TABLE_B b WHERE a.id = b.id 这是

  • 在Solr围绕原子更新的文档中,他们提到一个字段应该是非索引和非存储的。 https://lucene.apache.org/solr/guide/7_6/updating-parts-of-documents.html#in-place-update-example 只有当要更新的字段满足以下三个条件时,才使用该方法执行原子更新操作: 是非索引(indexed=“false”)、非存储(stor