对父类进行Hibernate查询会产生无效的联合查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对父类进行Hibernate查询会产生无效的联合查询相关的知识,希望对你有一定的参考价值。

我正在使用spring boot和hibernate,我有以下数据结构。

@Entity
public class Template {

  @Id
  private Integer id;

  @OneToMany(mappedBy = "template", orphanRemoval = true, fetch = FetchType.EAGER,cascade = CascadeType.ALL)
  @BatchSize(size = 30)
  private Collection<TemplateContent> contents;
}

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class TemplateContent {

  @Id
  private String contentType;

  @Id
  @ManyToOne(fetch = FetchType.EAGER, optional = false)
  @JoinColumn(name = "template_id", nullable = false)
  private Template template;
}

@Entity
public class SomeContent extends TemplateContent {

   private String someValue;
}

@Entity
public class SomeOtherContent extends TemplateContent {

   private String someOtherValue;
}

@Repository
public interface TemplateRepository extends JpaRepository<Template, Integer> {
  Page<Template> findByIdIn(Collection<Integer> ids, Pageable pageable);
}

当我调用findByIdIn方法时,它会生成以下查询:

SELECT ...
FROM   (SELECT content_type, 
               template_id, 
               some_value, 
               NULL AS some_other_value
        FROM   someContent
        UNION 
    SELECT content_type, 
               template_id, 
               some_other_value, 
               NULL AS some_value
        FROM   someOtherContent) contents0_ 
WHERE  contents0_.template_id IN ( ?, ?, ? ) 

这是无效的,因为mysql不能使用索引而不是派生表。有没有办法生成更有效的查询。

//this would be the desired query
SELECT ...
FROM   (SELECT content_type, 
               template_id, 
               some_value, 
               NULL AS some_other_value
        FROM   someContent
        WHERE template_id IN ( ?, ?, ? )
        UNION 
    SELECT content_type, 
               template_id, 
               some_other_value, 
               NULL AS some_value
        FROM   someOtherContent
        WHERE template_id IN ( ?, ?, ? )) contents_0_ ....

我也尝试使用不同的继承策略,但似乎所有这些都有类似的缺点。

答案

如果你想在多态查询中获得最佳性能,最好的方法是使用strategy = InheritanceType.SINGLE_TABLE,可能你会用空列支付性能,但它取决于哪个方面对你更重要,也因为strategy = InheritanceType.JOINED有同样的问题TABLE_PER_CLASS

以上是关于对父类进行Hibernate查询会产生无效的联合查询的主要内容,如果未能解决你的问题,请参考以下文章

本人新手 大家帮帮忙!hibernate 从子类查父类问题

hibernate创建本地查询后进行查询的时候报错: could not execute query;列名无效

面向对象:多态;

MySQL增删改查之多表联合查询

hibernate实现多表联合查询

hibernate实现多变联合查询