【问题标题】:How solve JPA lazy load problem with instanceof如何使用 instanceof 解决 JPA 延迟加载问题
【发布时间】:2019-05-26 04:38:00
【问题描述】:

我有那些 jpa 实体

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
class AbstarctAddress {


}

@Entity
public class ConsolidationHub extends AbstarctAddress {

}


@Entity
class Transport {

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "delivery_address_id")
   private AbstarctAddress address;

}

当我在做的时候

select t from Transport t left join fetch t.address

然后像这样检查instanceof

t.getAddress() instanceOf ConsolidationHub 它返回 false 。这是因为我得到了休眠代理。当我更改为 EAGER 时,我没有这个问题。但我不想放 EAGER,因为我有 EAGER 的性能问题。

你知道如何解决这个问题吗?

PS。我知道 instanceOf 检查是不好的做法,我只需要维护旧代码,其中有很多 instanceOf 检查,我现在无法重构所有这些。

【问题讨论】:

  • 我不知道如何让它在休眠状态下工作,抱歉。但是你真的在这里解决了正确的问题吗?为什么不解决性能问题?
  • 我在放 EAGER 时遇到性能问题,解决性能问题的一种方法是将其更改为惰性并使用 join fetch 编写 JPA 查询(但在这种情况下,我遇到了 instanceOf 的问题)。那么您还有其他建议吗?谢谢。@Jocke
  • @user1321466,尝试使用延迟加载的 t.getAddress().isAssignableFrom(ConsolidationHub.class)。
  • "instanceof" 在 Java 中是一个完全有效的操作。其他 JPA 提供商不会将其强加给您。 PS你拼错了“抽象”
  • 它可能不适用于您的情况,我还没有真正尝试过,但是可以使用 TYPE 运算符先验地限制查询获取的地址类型(参见JPA 2.1 规范中的第 4.6.17.5 节)。例如:SELECT t FROM Transport t LEFT JOIN FETCH t.address a WHERE TYPE(a)='ConsolidationHub'。我不确定它是否真的适用于人际关系。

标签: java hibernate jpa


【解决方案1】:

恐怕答案是:开始编写 OOP 代码。 instanceof 面对多态性。类的客户应该从不关心他们正在与哪个特定的子类型/实现对话。

如果您使用实体继承,现在需要在代码中使用instanceof,那么您的设计很可能存在缺陷。 Hibernate 在很多场合都使用代理,你不能依赖 instanceof.getClass() 总是返回你实体的确切类。

另一方面,如果您出于好奇使用了instanceof,并惊讶地发现它实际上返回了false,请不要担心,您对该实体代理的所有调用仍然是多态的。

这里instanceof失败的原因是Hibernate需要用something来初始化lazy属性,直到属性为加载。如果您坚持使用instanceof,您可以尝试启用实体增强。

【讨论】:

    猜你喜欢
    • 2011-07-27
    • 2011-05-22
    • 1970-01-01
    • 2014-03-06
    • 2013-09-07
    • 2020-12-02
    • 2020-01-23
    • 2011-12-20
    • 1970-01-01
    相关资源
    最近更新 更多