I'm coming from eclipselink and try to work myself through Hibernate.
Lets assume we have a class Car
and a class Wheel
. The Car
class has n wheels. Both entities are connected with a bidirectional association. More importantly on the Wheel
side I have a Car
reference:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "car_id")
private Car car;
plus a getter.
Now I want to fetch a wheel using its id. From my EntityManager
(not a hibernate Session
). I initialize the EntityManager
like this:
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = emf.createEntityManager();
The next step is to fetch a wheel like this:
Wheel wheel = em.find(Wheel.class, 1);
The wheel return the wanted class and its fine. Now I want to know which car is the parent of the wheel with something like:
Car car = wheel.getCar();
With eclipselink, the actual car would have been loaded. With hibernate a proxy class is loaded instead.
The only solution I worked out so far is to set the FetchType.EAGER or directly fetch join the relationship. What I realized is that the SQL statement in Hibernate is still executed, but no real object delivered. Also after
Hibernate.initalize(car)
I cannot retrieve the car entity.
Is there any way to get the expected object back without forming a query or an eager fetch?
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. This subclass will be the one to be returned instead of querying the database directly.
To enable lazy loading explicitly you must use “fetch = FetchType. LAZY” on an association that you want to lazy load when you are using hibernate annotations. @OneToMany( mappedBy = "category", fetch = FetchType.
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.
These data loading strategies we used when one entity class is having references to other Entities like Employee and Phone (phone in the employee). Lazy Loading − Associated data loads only when we explicitly call getter or size method. Use Lazy Loading when you are using one-to-many collections.
You probably don't need to worry about the proxy. The proxy should return all of the properties in the same way that the normal object will.
If the proxy object is not working (it is returning null values), it might be that some of your fields or setters or getters are set to final
. Check that out first.
You need to use the Hibernate specific LazyToOneOption.NO_PROXY annotation:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "car_id")
@LazyToOne(LazyToOneOption.NO_PROXY)
private Car car;
This will instruct Hibernate to load the actual object, instead of giving you a Proxy:
Lazy, give back the real object loaded when a reference is requested (Bytecode enhancement is mandatory for this option, fall back to PROXY if the class is not enhanced) This option should be avoided unless you can't afford the use of proxies
But you'll have to use Bytecode instrumentation to activate this option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With