Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Hibernate FetchProfile to load deep child objects in the hierarchy

I have the same question as someone posted in the Hibernate Community: FetchProfiles.

For performance reasons I have a relationship in the data model as follows:

...C -[FetchType.LAZY]-> D -> [FetchType.LAZY] -> E

Using FetchProfile I can eagerly load D with C, but I can't figure out how to eagerly load E. I know I can successfully use a NamedQuery using inner joins, but it really bugs me that I can't work out how to do it using FetchProfile. An example of an attempted FetchProfile (anything else is lost in the mists of time):

@FetchProfile(name = "cwithDAndE", fetchOverrides = {
        @FetchProfile.FetchOverride(entity = C.class, association = "dByCId", mode = FetchMode.JOIN),
        @FetchProfile.FetchOverride(entity = D.class, association = "eByDId", mode = FetchMode.JOIN)
})

I enable the FetchProfile for the session and successfully use a session.get with no error and C and D populated - E is still lazy and unpopulated. In desperation I remember trying a dot notation for the association from C downwards. I can only find examples that have a depth of one.

This is an OCD type gap in my knowledge that needs filling!

Thanks in advance for any help.

like image 583
Anthony Avatar asked Mar 25 '11 10:03

Anthony


1 Answers

You have a A obj containing a B obj, containing a C obj. By default they are

...A -[FetchType.LAZY]-> B -> [FetchType.LAZY] -> C

A class:

@FetchProfiles({
    @FetchProfile(fetchOverrides = { @FetchOverride(association = "b", entity = A.class, mode = FetchMode.JOIN) }, name = "a-with-b")
    })
@Entity
@Table(name="EDITOR_IDENTITIES")
public class A {
    private B b;    
    //...
}

B class:

@FetchProfiles({
    @FetchProfile(fetchOverrides = { @FetchOverride(association = "c", entity = B.class, mode = FetchMode.JOIN) }, name = "b-with-c")
    })
@Entity
@Table(name="EDITOR_IDENTITIES")
public class B {
    private C c;    
    //...
}

ADao class:

@Repository(value="aDaoImpl")
@Transactional
public class ADaoImpl {

    @Override
    public A loadByPrimaryKey(long id)
    {   
        Session session = sessionFactory.getCurrentSession();
        session.enableFetchProfile("a-with-b");
        session.enableFetchProfile("b-with-c");
        Criteria criteria = session.createCriteria(A.class);
        criteria.add(Restrictions.eq("id", id));
        A a = (A) criteria.uniqueResult();
        if(identity != null)
            return identity;
        else
            return null;
    }
}

you will get A filled with B filled with C. This is a very basic solution, you can build a Dao method taking a list of fetch profile as argument.

like image 95
MaVVamaldo Avatar answered Nov 09 '22 03:11

MaVVamaldo