Home How to force hibernate not to load subentities
Reply: 2

How to force hibernate not to load subentities

simon77
1#
simon77 Published in 2017-12-06 12:16:48Z

I have A and B entities where A can have more Bs

@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;

}

what I need is to say jpa somehow not to load set of Bs in special situations.

I tried it other way around, I defined fetch = FetchType.Lazy and then I say hibernate when i want to load B. Problem is however, that when i do a.getBs(), hibernate loads the bs even when i dont want this behaviour ( I wanted only check if B is loaded or not). It means I need to force hibernate with jpa not to load subentities later (a.getBs()) with lazy load mode OR to force not to load entities with eager load mode.

In jpa there is method Root.fetch(). I would need Root.unfetch()

forgivenson
2#
forgivenson Reply to 2017-12-06 15:54:57Z

One way I can think of is to move a out of the method that creates the transaction, and then call a.getBs(). If you have it lazy loaded, it won't be able to fetch it outside of the transaction.

For example:

@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
}
Zeromus
3#
Zeromus Reply to 2017-12-06 13:27:13Z

Hibernate provide functionality for the check without fetching.

If you keep Lazy fetching you can add this method in the parent entity

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

The point is to not call the getter or you will fetch the association

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.33543 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO