Search code examples
hibernateormjpacollectionssecond-level-cache

Different cache concurrent strategies for root entity and its collection (Hibernate with EHCache)?


Given example from Hibernate docs and modifying it so that root level entity (Customer) is read-only while one of its collections (tickets) is read-write:

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Customer { 
    ... 
    @OneToMany(...)
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public SortedSet<Ticket> getTickets() {
        return tickets;
    }
    ...
}

Would collection of tickets get refreshed when accessing customer from cache?


Solution

  • If you modify one of the tickets of a given Customer somewhere else, yes. Why don't you test this? Let's assume Cutomer#1 has Ticket#1 and Ticket#2 in its tickets collection. I ran this code:

    // loading in first session
    Session session1 = HibernateUtil.getSession();
    Transaction tx1 = session1.beginTransaction();
    Customer c1 = (Customer) session1.load(Customer.class, 1L); // loads from db and puts in cache
    for (Ticket ticket : c1.getTickets()) { // caches q2742145.Customer.tickets#1
        System.out.println(ticket);
    }
    Ticket ticket = (Ticket) session1.load(Ticket.class, 1L); // doesn't hit the db
    ticket.setName("foo"); // do some change on Ticket#1
    session1.save(ticket);
    tx1.commit(); // Ticket#1 gets updated in the db and the cached association invalidated
    
    // loading in second session
    Session session2 = HibernateUtil.getSession();
    Transaction tx2 = session2.beginTransaction();
    Customer c2 = (Customer) session2.load(Customer.class, 1L); // hits the cache
    Set<Ticket> tickets = c2.getTickets();
    for (Ticket ticket2 : tickets) { // reloads tickets from db
        System.out.println(ticket2); 
    }
    tx2.commit();
    

    Which shows the collection of tickets gets "refreshed".