Hibernate - 加入策略选择了太多列

Posted

技术标签:

【中文标题】Hibernate - 加入策略选择了太多列【英文标题】:Hibernate - joined strategy selects too many columns 【发布时间】:2020-10-06 19:02:41 【问题描述】:

我们在 JBoss eap 6.3 和 PostgreSQL 12 上使用 Hibernate 4.2.14。在我们的应用程序上,我们使用“加入”继承策略。

当我们查询超类时出现问题,然后hibernate尝试加入继承的所有子类并选择所有子类的所有列,然后点击“目标列表最多可以有1664个条目” Postgres错误.

可以使用鉴别器列作为解决方案吗?在那种情况下,hibernate 将知道要查询哪个子类,并且应该只将超类与特定的子类连接起来,避免导致错误的巨大选择。那可能吗 ?我们错过了什么吗?

【问题讨论】:

【参考方案1】:

在 Hibernate 5.4 中,这被优化为只执行真正必要的连接,但可能仍然存在这种情况发生的情况,我因为你似乎在做连接获取更新不会让你免于这种情况。对于某些关联,您必须使用不同的获取策略来减少连接和选择项目的数量。更多信息请看这里:https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#fetching-fetch-annotation

如果您还想通过减少要选择的列的数量来进一步提高性能,您还可以重写查询以不使用实体的连接提取,而是只选择您真正需要的实体字段。这是Blaze-Persistence Entity Views 的完美用例。

我创建了该库以允许在 JPA 模型和自定义接口或抽象类定义模型之间轻松映射,例如 Spring Data Projections on steroids。这个想法是您按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

使用 Blaze-Persistence Entity-Views 的用例的 DTO 模型可能如下所示:

@EntityView(A.class)
public interface ADto 
    @IdMapping
    Long getId();
    String getName();
    @Mapping("bCollection")
    Set<BDto> getBs();

    @EntityView(B.class)
    interface BDto 
        @IdMapping
        Long getId();
        String getName();
    

查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

ADto a = entityViewManager.find(entityManager, ADto.class, id);

Spring Data 集成让您可以像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

Blaze-Persistence Entity-Views 也支持获取策略的概念

【讨论】:

我已经更新了问题,hibernate选择了子类的所有列,在hibernate 5上是固定的吗? 是否可以在运行 jpa 2.1 的 jboss eap 6.3 上运行 hibernate 5.4? 这不是固定的,不。这正是获取实体所需要做的事情。也许您应该对某些关联使用不同的获取策略。

以上是关于Hibernate - 加入策略选择了太多列的主要内容,如果未能解决你的问题,请参考以下文章

Java 11:OSGi:生成 EntityManager,无法构建 Hibernate SessionFactory java.lang.ClassNotFoundException:org.hib

Hibernate注解配置与XML配置区别

Hibernate参考文档

在多列上连接大量表的策略?

一 Mybatis概述&与Hibernate的区别&CRUD

Hibernate 花费了太多时间并执行了一些神秘的操作。