afaik entities are indexed just by their primary key in the 2nd level cache, so querying related entities won't make use of it:
@Entity
public class Employee {
@Id
@Column(name="EMP_ID")
private long id;
...
@OneToMany(mappedBy="owner")
private List<Phone> phones;
...
}
@Entity
public class Phone {
@Id
private long id;
...
@ManyToOne
@JoinColumn(name="OWNER_ID")
private Employee owner;
...
}
EntityManager em;
// uses 2nd level cache
Employee employee = em.find(Employee.class, 1);
// doesn't use 2nd level cache. Even if 2nd level cache actually
// contains all referenced phones, there will be a DB call.
employee.getPhones();
Is it possible to avoid the db call, when accessing phones and make use of the 2nd level cache? Is there a cache implementation supporting custom indexing?
I'm currently using wildfly 14 with hibernate/infinispan.
Will accessing phones at least make use of query cache or just em.createQuery(...)
?
I finally found a solution. There is a collection cache in Hibernate which has to be explicitly enabled by annotating the collection with org.hibernate.annotations.Cache
.
@Entity
@Cacheable(true)
public class Employee {
@Id
@Column(name="EMP_ID")
private long id;
...
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@OneToMany(mappedBy="owner")
private List<Phone> phones;
...
}
It works perfectly!