João Menighin
João Menighin

Reputation: 3225

Eager fetch an specific lazy property for a particular object

I have the following model:

@Table(name = "foo")
public class Foo {

    @ManyToOne(fetch = FetchType.LAZY)
    private Bar bar;

}

Using Entity Framework in .NET in a similar situation, I could eagerly bring the Bar property with something like:

context.Foo.Include(f => f.bar).First()

Is there anything equivalent with Hibernate?

My situation is that I'm saving an object with a lazy property into a session in my server. Then when I retrieve the session properties, I cannot access the lazy property for the Hibernate Session is already gone. I cannot put this property as EAGER because it is inherited from a @MappedSuperclass used by a lot of other classes.

Thanks for any help.

Upvotes: 0

Views: 1206

Answers (2)

Aleksandr Semyannikov
Aleksandr Semyannikov

Reputation: 1442

  1. JPA EntityGraph:

    @Entity
    @Table(name = "foo")
    @NamedEntityGraph(name = "foo.bar",
            attributeNodes = @NamedAttributeNode("bar")
    )
    public class Foo {
    
        @ManyToOne(fetch = FetchType.LAZY)
        private Bar bar;
    
    }
    
    Foo foo = entityManager.find(
        Foo.class,
        id,
        Collections.singletonMap(
            "javax.persistence.fetchgraph",
            entityManager.getEntityGraph("foo.bar")
        )
    );
    

    You can see another example and more detail explanation there.

  2. Hibernate profiles:

    @Entity
    @Table(name = "foo")
    @FetchProfile(
        name = "foo.bar",
        fetchOverrides = {
            @FetchProfile.FetchOverride(
                entity = Foo.class,
                association = "bar",
                mode = FetchMode.JOIN
            )
        }
    )
    public class Foo {
        @ManyToOne(fetch = FetchType.LAZY)
        private Bar bar;
    }
    
    
    session.enableFetchProfile("foo.bar");
    Foo foo = session.byId(Foo.class).load(id);
    

Upvotes: 3

Lorelorelore
Lorelorelore

Reputation: 3393

You can use a JPQL query with FETCH JOIN:

List<Foo> l = em.createQuery(
    "SELECT f FROM Foo f JOIN FETCH f.bar", Foo.class)
    .getResultList();

In this way all Foo class instances will be loaded with all Bar instances already fetched. You can tailor the query to fit your needs.

Upvotes: 1

Related Questions