Java 对父类的Hibernate查询会创建无效的联合查询
我使用SpringBoot和hibernate,我有以下数据结构Java 对父类的Hibernate查询会创建无效的联合查询,java,spring,hibernate,spring-boot,spring-data-jpa,Java,Spring,Hibernate,Spring Boot,Spring Data Jpa,我使用SpringBoot和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&l
@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);
}
这是无效的,因为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.JOINED
具有与TABLE\u PER\u CLASS
相同的问题。您尝试过单表策略吗?实际内容具有完全不同的数据结构,因此我尝试不将所有内容保存在一个表中。另外,我有8种不同的内容类型。问题是我有不同的内容类型,而且每种类型都有完全不同的数据模型。我想知道是否有一种方法可以“提示”hibernate来生成一个正确的查询。它已经是一个正确的查询了。正如你所说,对于完全不同的模型数据,你所拥有的多态性是不恰当的。你能不能解释一下,数据模型有什么问题。我有大约8种内容类型,每种类型都有5-6个特定于其类型的字段,还有4个与其他内容类型共享的其他字段。创建一个包含50列的表在某一点上是没有意义的,内容类型可以随着时间的推移而增强。一边是50列,另一边是8个表之间的连接。合理与否只取决于您的需求和场景。
//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_ ....