oliverkn
oliverkn

Reputation: 743

Initialize all properties of a proxy in Hibernate

I´m using Spring JpaRepository to access the database. My goal is to create a method which finds one entity and fully initializes it. Currently I´m doing it like that:

Hibernate.initialize(business.getCollectionA());
Hibernate.initialize(business.getCollectionB());
Hibernate.initialize(business.getCollectionC());

So I search for a method which initializes all collections at once like that:

Hibernate.initializeAll(business);

Upvotes: 0

Views: 3480

Answers (3)

geert3
geert3

Reputation: 7331

How about this:

    import org.hibernate.SessionFactory;
    import org.hibernate.metadata.ClassMetadata;
    import org.hibernate.type.CollectionType;
    import org.hibernate.type.Type;

    // you should already have these somewhere:
    SessionFactory sessionFactory = ...
    Session session = ...
    MyEntity myEntity = ...

    // this fetches all collections by inspecting the Hibernate Metadata.
    ClassMetadata classMetadata = sessionFactory.getClassMetadata(MyEntity.class);
    String[] propertyNames = classMetadata.getPropertyNames();
    for (String name : propertyNames)
    {
        Object propertyValue = classMetadata.getPropertyValue(myEntity, name, EntityMode.POJO);
        Type propertyType = classMetadata.getPropertyType(name);
        if (propertyValue != null && propertyType instanceof CollectionType)
        {
            CollectionType s = (CollectionType) propertyType;
            s.getElementsIterator(propertyValue, session);   // this triggers the loading of the data
        }
    }

Upvotes: 0

Ankur Singhal
Ankur Singhal

Reputation: 26077

As such Hibernate or JPA does not provide any utility to initialize all lazy properties for the entity.

You need to write your recursive logic, using Java Reflection to traverse the tree and initialize the objects.

You can find here more or less what you want.

Upvotes: 1

geert3
geert3

Reputation: 7331

You can mark you collection properties as FetchType.EAGER to make them loaded automatically as soon as the Entity is loaded.

e.g.

@OneToMany(fetch=FetchType.EAGER)
private Set collectionA;

Add this fetchtype to any collection you want "initialized". Note that this kills performance, but it has the same effect as invoking initialize on each collection.

Upvotes: 0

Related Questions