Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java/Hibernate: How to detect, if field is lazy-loaded proxy and not actual data?

I'm converting my entity to DTO and I want to set NULL as DTO value for all fields, which are lazy-loaded and not initialized (because I do not want to transfer all the data all the time).

I've tried:

if (!(entity.getNationality() instanceof HibernateProxy))
    this.setNationalityFromEntity(entity.getNationality());

But it did not seemed to help. Any suggestions are welcome!

Thank you!

like image 681
Miro Hudak Avatar asked Apr 08 '13 23:04

Miro Hudak


People also ask

What is proxy in Hibernate lazy loading?

By definition, a proxy is “a function authorized to act as the deputy or substitute for another”. This applies to Hibernate when we call Session. load() to create what is called an uninitialized proxy of our desired entity class. Simply put, Hibernate subclasses our entity class, using the CGLib library.

How does lazy loading works in Hibernate How will load a lazily loaded items in Hibernate to avoid lazy load exception?

7. Lazy Loading in Hibernate. Hibernate applies lazy loading approach on entities and associations by providing a proxy implementation of classes. Hibernate intercepts calls to an entity by substituting it with a proxy derived from an entity's class.

What is the result of lazy loading in Hibernate?

Lazy loading in Hibernate means fetching and loading the data, only when it is needed, from a persistent storage like a database. Lazy loading improves the performance of data fetching and significantly reduces the memory footprint.

Is Hibernate lazy load by default?

By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for most associations in the majority of applications. If you set hibernate.


2 Answers

They way we do this in our Entities is we have boolean methods which do the check in a way that will not trigger the lazy loading. For example, if our Entity had an associated entity called 'associatedSomething', then the method to check if that associated Entity has been lazy loaded would be:

    public boolean isAssociatedSomethingLoaded() {
        if (associatedSomething instanceof HibernateProxy) {
            if (((HibernateProxy)associatedSomething).getHibernateLazyInitializer().isUninitialized()) {
                return false;
            }
        }
        return (getAssociatedSomething() != null);
    }

NOTE: It's important not to use getAssociatedSomething() in the check, as this makes sure that the associated Entity does not get lazy-loaded during the check.

like image 66
DuncanKinnear Avatar answered Oct 17 '22 00:10

DuncanKinnear


The class is always a proxy, whether it's initialized or not, so you're going to exclude it every time if you just check for instances of proxy. The Lazy Load does not cause the Proxy reference on the entity to be replaced with a reference to a new object, it just populates the fields.

To find out if it's actually initialized you need to ask it!

if (HibernateProxy.class.isInstance(entity.getNationality())) {
  HibernateProxy proxy = HibernateProxy.class.cast(entity.getNationality());
  if (!proxy.getHibernateLazyInitializer().isUninitialized()) {
    this.setNationalityFromEntity(entity.getNationality());
  }
}
like image 4
Affe Avatar answered Oct 17 '22 00:10

Affe