2

I seem to have an odd caching problem (I guess) for NamedQuery which I can not seem to resolve.

Here are some details:

I have a Process, ProcessForm and ProcessFormModule tables and related entities - which are all linked using standard @JoinColumn annotations like this:

@JoinColumn(name = "process_id", referencedColumnName = "id", insertable = false, updatable = false)
@OneToMany(fetch = FetchType.EAGER)
private List<ProcessForm> processForms;

Then I have Elements which need to be linked programatically to specific module because I need to fill the list in runtime. The reason why this needs to be filled in runtime is that I have more Element for each module for a specific language and when the form is started, Elements need to be filled related to given URL parameters.

This is how the field is defined in ProcessFormModule entity - just a simple object list:

@Transient
private List<Mle> mles;

This method is finally called for each module to fill the Elements:

public List<Mle> getMLEsByMRL(Long moduleId, Long regionId, Long languageId) {
    List<Mle> items = null;

    Query query = em.createNamedQuery("Mle.findByMRL", Mle.class);

    items = query
      .setParameter("moduleId", moduleId)
      .setParameter("regionId", regionId)
      .setParameter("languageId", languageId)
      .getResultList();

    return items;
  }

The used NamedQuery is defined like this:

@NamedQuery(name = "Mle.findByMRL", query = "SELECT m FROM Mle m WHERE m.moduleId = :moduleId AND m.regionId = :regionId AND m.languageId = :languageId")})

Also, probably important - each manager is derived from AbstractManager which looks like this:

public abstract class AbstractManager {
  @PersistenceUnit
  protected EntityManagerFactory emf;
  protected EntityManager em;

  @PostConstruct
  protected void initialize() {
    em = emf.createEntityManager();
  }

  @PreDestroy
  protected void cleanup() {
    if (em.isOpen()) {
      em.clear();
      em.close();
    }
  }
}

Now to the problem - When I try to force no cache usage for this query, nothing seems to be working. I've tried changing persistence.xml, adding properties to each EntityManager, hints for the NamedQuery - basically all I could find here and elsewhere, but to no effect. I've even tried the evictAll just before query is executed:

em.getEntityManagerFactory().getCache().evictAll();

I keep getting stale results - but only for this programatically filled list! If I change anything else from applications CRUD or other screens, all is well. But in case I change which elements are used in the module (from app screens which are using entities or by changing the data directly in DB [which is MySQL] - nothing. I have to restart the app in order to get current and fresh records from DB.

daxur
  • 359
  • 1
  • 11
  • I see that you're manually creating and closing the entity manager, which is quite strange. This suggests that you're not taking benefit of Java EE container managed transactions, which in turn would possibly explain your problem: you're never committing the transactions. You've 2 options: 1) use container managed transactions, or 2) manage transactions yourself. I suggest to go through a decent JPA tutorial which is targeted on a Java EE environment. You shouldn't have anything like an `AbstractManager` (unless you develop for Tomcat/Jetty, which actually isn't a Java EE container at all). – BalusC Jul 27 '13 at 20:23
  • AbstractManager was an attempt to fix a certain deadlock - it obviously introduced another set of problems. Now I just changed it to: `@PersistenceContext(unitName = "mdr-ejbPU") protected EntityManager em;` and removed the manual creation and clearing. It seems to be working, but there is another drawback. Now everything seems to be slugish again as if the cache is not used at all. I don't have any settings left in persisence.xml for cache so everything is on their defaults. Could you perhaps recommend some decent JPA tutorial since it seems that I'm missing some finer points. Thank you. – daxur Jul 27 '13 at 22:20

0 Answers0