Search code examples
javajakarta-eejpaeclipselink

How to refresh cache after persist?


I am using JPA (EclipseLink 2.5) for persistence. My web app contains AJAX page updates. When a post is saved, the posted content shows up without refreshing the browser. The post have tags associated with it using a OneToMany relationship. These tags are supposed to show up after save too. However, because the cache was enabled I was not able to get the tags.

Here's my code:

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
public Sqask save(AskTag tags) {
    try {
        Sqask ask = saveAsk(tags);
        return ask;
    } catch (Exception e) {
        context.setRollbackOnly();
        return null;
    }
}

public Sqask saveAsk(AskTag tags) {
        Sqask ask = new Sqask();
        ask.setCreator(tags.getAskedBy());
        em.persist(ask);
        em.flush();
        saveTags(tags, ask);
        return ask;
    }

public void saveTags(AskTag tags, Sqask ask) {
        if (!tags.getNask().isEmpty()) {
            NAsk nask = new NAsk();
            NAskPK naskPK = new NAskPK();
            naskPK.setAsk(ask.getId());
            naskPK.setNoun(tags.getNask());
            naskPK.setCreator(tags.getAskedBy().getGuid());
            nask.setNAskPK(naskPK);
            nask.setAsk(ask);
            nask.setCreator(tags.getAskedBy());
            em.persist(nask);
        }

        if (!tags.getVask().isEmpty()) {
            VAsk vask = new VAsk();
            VAskPK vaskPK = new VAskPK();
            vaskPK.setAsk(ask.getId());
            vaskPK.setVerb(tags.getVask());
            vaskPK.setCreator(tags.getAskedBy().getGuid());
            vask.setVAskPK(vaskPK);
            vask.setAsk(ask);
            vask.setCreator(tags.getAskedBy());
            em.persist(vask);
        }

        if (!tags.getForask().isEmpty()) {
            PAsk forask = new PAsk();
            PAskPK foraskPK = new PAskPK();
            foraskPK.setAsk(ask.getId());
            foraskPK.setPrep(tags.getForask());
            foraskPK.setCreator(tags.getAskedBy().getGuid());
            forask.setPAskPK(foraskPK);
            forask.setAsk(ask);
            forask.setCreator(tags.getAskedBy());
            em.persist(forask);
        }

        if (!tags.getAboutask().isEmpty()) {
            PAsk aboutask = new PAsk();
            PAskPK aboutaskPK = new PAskPK();
            aboutaskPK.setAsk(ask.getId());
            aboutaskPK.setPrep(tags.getAboutask());
            aboutaskPK.setCreator(tags.getAskedBy().getGuid());
            aboutask.setPAskPK(aboutaskPK);
            aboutask.setAsk(ask);
            aboutask.setCreator(tags.getAskedBy());
            em.persist(aboutask);
        }

        em.getEntityManagerFactory().getCache().evict(Sqask.class, ask.getId());
        em.merge(ask);
}

How can I get things to work? How to refresh an entity with all its associated entities? Thanks.


Solution

  • If I understand your question correctly maybe this could help you - please notice em.refresh call before returning. This ensured that all OneToOne and OneToMany joins are refreshed, even if you are only saving an ID of related record.

    public T create(T entity) {
      em.persist(entity);
      em.flush();
      em.refresh(entity); // this could be important
      return entity;
    }