如何强制休眠不加载子实体

时间:2017-12-06 12:16:49

标签: java hibernate jpa

我有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然后我说hibernate当我想加载B.问题是,当我做a.getBs()时,hibernate加载bs即使我不想要这种行为(我只想检查B是否加载)。这意味着我需要使用jpa强制hibernate以后不使用延迟加载模式加载子实体(a.getBs())或强制不加载具有急切加载模式的实体。

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

2 个答案:

答案 0 :(得分:0)

我能想到的一种方法是将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
}

答案 1 :(得分:0)

Hibernate提供检查功能而无需提取。

如果你保持Lazy抓取 您可以在父实体中添加此方法

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

重点是不要调用getter,否则你将获取关联