I'm now using the JPA2 @Cacheable annotation on my Entities, and all is working well.
I now need to cache a ManyToOne association.
In classic Hibernate, it was necessary to annotate the association with @Cache.
@org.hibernate.annotations.Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Student> supervisionGroup;
And this works. But it seems we cannot use the JPA2 @Cacheable annotation on anything other than the entity itself.
Am I missing something, or were the JPA committee too dim to realise that associations have to be cached as well as entities? Surely it can't be the dim option??
I think after some research I'm able to answer my own question. The key is that Hibernate dehydrates objects in the 2LC and this will influence whether you need to explicitly cache the associations.
Please add more details if I've missed anything or got any detail wrong.
Here's a simplified class structure:
@Entity
@Cacheable
public class Tutor
{
@OneToMany(mappedBy="tutor")
private Set<Student> students;
}
@Entity
@Cacheable
public class Student
{
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="TUTOR_FK")
private Tutor tutor;
}
The Second Level Cache (2LC) stores entities in a dehydrated form, eg:
{1=CacheEntry(Tutor)[1, Jack Daw]}
{1=CacheEntry(Student)[1, Jane Smith, 1]}
The final 1 in the Student data is the foreign key to tutor.
So if you have a reference to Student id 1 and follow the reference to the tutor, we get a cache hit because the foreign key is in the cache. No extra select is needed.
However, if you go the other way, calling getStudents() on the Tutor, there is no foreign key in the 2LC so a select is needed. (once the select completes, hibernate has the ids and can start hitting the 2LC).
To avoid this, you will need to add the old org.hibernate.annotations.Cache annotation to the @OneToMany relationship.
I don't have an EclipseLink installation to hand so I can't test this but I understand that EclipseLink stores the 2LC data in the form of the original object graph, so the above isn't relevant. As per Chris' answer, the entity is cached with its references so further annotating isn't needed.
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