How to Convert a Hibernate Proxy to a Real Entity Object

How to convert a Hibernate proxy to a real entity object

Here's a method I'm using.

public static <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
throw new
NullPointerException("Entity passed for initialization is null");
}

Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
.getImplementation();
}
return entity;
}

JPA/Hibernate proxy not fetching real object data, sets all properties to null

As JB Nizet suggested, the final modifier in my classes' getters was messing with the proxies hibernate creates for lazy loaded relationships.

how to unproxy a hibernate object

Here's our solution, added to our persistence utils:

public T unproxy(T proxied)
{
T entity = proxied;
if (entity instanceof HibernateProxy) {
Hibernate.initialize(entity);
entity = (T) ((HibernateProxy) entity)
.getHibernateLazyInitializer()
.getImplementation();
}
return entity;
}

Hibernate returns proxy for base class

Can't be certain without seeing more of the object model, but one reason Hibernate would do this is if the BaseEntity had already had to be resolved as a proxy for the same BaseEntity.id earlier in the session.

For example, if there is another class that has a ToOne relation to a BaseEntity, it will just have a foreign key to the id, so will use a BaseEntity_$$... proxy to delay resolving the correct subclass for the other end. This then becomes the instance for that id that is managed in the Hibernate PersistenceContext.

Clearly a Hibernate.unwrap(), or one of the other options in the link above will reveal the 'true' instance. One other option is to use abstract methods on BaseEntity (e.g. isIndividual()). This can look a bit tidier, but ultimately Hibernate will still need to resolve the proxy when the method is called.

How does Hibernate implement Proxy Objects?

Hibernate use javassist to create dynamic proxies instead of concrete entities to populate fields of fetched entity that are referencing other persistent entity (or collection of persistent entities).

(note that if you mark the relationship as eagerly fetched : hibernate won't create proxies but concrete entities. This is NOT the default)

A major advantage of javassist over standard dynamic proxy mechanism is that it allows creation of dynamic proxy on concrete classes, not only interfaces.

The responsability of a proxy is to perform "transparently" a database read operation when required (i.e. when access to a proxied entity is required)

Proxies and first or second level cache aren't really linked concepts. We can just say that if you try to "resolve" a proxy when the entity holding it isn't attached to an open session (i.e. when the entity holding it isn't in the first level cache) it will raise a LazyInitializationException (simply because there is no way perform a database read in this situation)

How to retrieve an Entity Object just with @Id (Proxy object), check if it exists and assign it to a @ManyToOne association

I don't understand what the problem is. Just use getOne approach and at the end of your method, use flush which will throw the constraint violation exception that you can handle. This is the way to go.



Related Topics



Leave a reply



Submit