【问题标题】:How to force hibernate not to load subentities如何强制休眠不加载子实体
【发布时间】:2017-12-06 12:16:48
【问题描述】:

我有 A 和 B 实体,其中 A 可以有更多 B

@Entity
@Table(name = "A")
public class A {

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "b_id", nullable = false, insertable = true, updatable = false)
private Set<B> bs;

}

我需要说 jpa 在特殊情况下不加载 B 集。

我尝试了另一种方法,我定义了 fetch = FetchType.Lazy,然后当我想加载 B 时我说休眠。但是问题是,当我执行 a.getBs() 时,即使我执行休眠也会加载 bs不想要这种行为(我只想检查 B 是否已加载)。这意味着我需要强制使用 jpa 休眠,以便以后不使用延迟加载模式加载子实体(a.getBs()),或者强制不使用急切加载模式加载实体。

在 jpa 中有方法 Root.fetch()。我需要 Root.unfetch()

【问题讨论】:

  • 您能解释一下为什么需要这样做吗?如果人们知道您要完成的工作,您将获得更好的帮助。
  • 如果我理解正确,当您调用 a.getBs 时您不想加载 bs?
  • 是的。当我调用 a.getBs 时,我不想加载 bs。 @forgivenson 我将实体重新映射到模型,我只想重新映射那些已在第一个查询中加载的实体
  • 这有意义吗?如果你不想要 B 不要调用 getter?
  • @Zeromus 是的。基于此(已加载或未加载),我执行其他功能

标签: java hibernate jpa


【解决方案1】:

Hibernate 提供无需获取的检查功能。

如果你继续 Lazy fetching 您可以在父实体中添加此方法

public boolean isBLoaded() {
    if (bs instanceof HibernateProxy) {
        if (((HibernateProxy)bs ).getHibernateLazyInitializer().isUninitialized()) {
            return false;
        }
    }
    return true;
}

关键是不要调用getter,否则你会获取关联

【讨论】:

  • 有对应的 JPA API 吗?
  • 抱歉,我不知道,但是如果您不关心暴露 Hibernate 特定的 API(您不会更改 jpa 提供程序),它应该可以正常工作
  • 好吧,实际上它可能在未来发生。这就是我们与 JPA 合作的原因。不过还是谢谢:)
【解决方案2】:

我能想到的一种方法是将a移出创建事务的方法,然后调用a.getBs()。如果您延迟加载它,它将无法在事务之外获取它。

例如:

@Entity
@Table(name = "A")
public class A {

    // this must be LAZY for this to work
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "b_id", nullable = false, insertable = true, updatable = false)
    private Set<B> bs;

}

...

public void outsideTransaction() {
    A a = getA();

    // a.getBs() will return null if it was never called inside method getA()
    if(a.getBs() == null) {
        // do stuff
    } else {
        // do other stuff
    }
}

public A getA() {
    // transaction starts in this method, however you are handling transactions
    A a = // query for record from table A;

    // do stuff that may or may not involve calling a.getBs()

    return a;
    // transaction ends
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多