I feel that the original answer does not cover entirly why this is happening.
Why OneToOne is not cached ?
It is not cached because class A
is not the owner of the relationship and does not contain the @JoinColumn inside its table. Therefore there is no way for class A
to tell what is the ID
of class B
. This is why when trying to retrieve class A
it needs to send a query for class B
to figure out what the ID of class B is, but when it sends the query the class B
is already loaded so there is no need for it to actualy retrieve it from the cache.
When OneToOne will be cached ?
Now if you navigate the opposite way from class B
to class A
then you will hit the cache straight away :)
Why is @OneToMany(cascade={}, fetch=FetchType.EAGER, mappedBy="a") working ?
In hibernate collections are cached in their dedicated region known as collection cache. Hibernate caches the primary keys of the entities that make up the collection. Not the entities themselves; i.e. there is no Set stored somewhere in the second level cache.
Once the primary key for is retrieved from the collection cache region it falls back to the regular entity cache to retrieve the actual object. Therefore the @OneToMany
hack works for you.