Why does hibernate return a proxy object?

I have a service method that calls a DAO, which then returns an object from the database. This method is called from numerous parts of the system. However, one method is to obtain the return type of the ObjectClass _ $$ _ javassist_somenumber. What throws things away. I call the service method exactly the same as everywhere else, so why does hibernate return a proxy server as opposed to a natural object?

I know that there are ways to expose a “proxied” object, but I don’t feel that I have to.

The request is simple

hibernateTemplate.find("from User u where u.username = ?", username) 

I am using hibernate 3.3 btw.

+4
source share
3 answers

This is a proxy object to support lazy loading; basically, as soon as you reference the child or lookup object via accessor / getter methods, if the related object is not in the session cache, then the proxy code will be passed to the database and load the associated object. It uses javassist to efficiently dynamically create subclassed implementations of your objects (although I think it can be configured to use CGLIB ).

If it had not been proxied in this way, it would be impossible to implement seamless lazy loading.

I can’t remember the top of my head, regardless of whether you use active loading, a natural object will be returned instead. Normally, I would not recommend using a downloadable load, especially if you have many related child objects, as this could soon become a huge performance bottleneck, as it would suck every related object into memory.

Also, if you need to distinguish between the type of a class, rather than using obj.getClass() , use Hibernate.getClass(obj) , which will return you a class of natural objects whether it is proxied or not: see the Hibernate Javadocs API here .

+9
source

Hibernate returns proxies if not all members are allowed, i.e. The object is not completed. This is often the desired feature to improve performance and is (I think) the default setting in sleep mode.

If you do not want proxies, you can suppress lazy loading in the hbm.xml file, i.e. use active loading. Please check hibernate docs for exact syntax.

To use a proxy object, simply never access the element directly, but only through getter, even inside member functions. Hibernation magic fills a member when you receive it. Thus, you will never have to expose an object. Also, do not use instanceof for potential proxy objects. But in any case, this is the smell of code.

+2
source

In my opinion this expression:

 hibernateTemplate.find("from User u where u.username = ?", username) 

It should always return a POJO, not a proxy. This is because the standard HQL criteria / criteria returns an unproxed object, but the objects of your original entity classes. This is different from lazy associations :

 @Entity class X { @ManyToOne(fetch = FetchType.LAZY) private User user; } 

Getting the X object from db here, we will have a lazy proxy in the X.user field (proxied User instance).

Now it happens that when executing from User where [...] you sometimes have a POJO, and sometimes a proxy object. Usually this is due to the fact that in some executions the User object was first extracted from db through associations (the from X where [...] request was called first in this sleep mode session). Having an already (proxied) instance of User , hibernate will reuse that instance even for your simple queries such as from User where [...] .

0
source

Source: https://habr.com/ru/post/1306281/


All Articles