0

I use Hibernate JPA for my web application and I use Apache Tomcat for my web server. My problem is, after updating my entity obj, I call the another function to get the entity list. In that entity list, I see the old object instead of the updated one.

I check in the database and the record is updated already. But EntityManager is returning the old object.

Here is my persistence.xml :

<?xml version="1.0" encoding="UTF-8" ?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="Default" transaction-type="RESOURCE_LOCAL">
    <description>
      Persistence unit for the Envers tutorial of the Hibernate Getting Started Guide
    </description>
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jar-file>D:\Projects\JPATempJars\com.mbc.common.jar</jar-file>
    <jar-file>D:\Projects\JPATempJars\com.mbc.hr.jar</jar-file>
    <shared-cache-mode>NONE</shared-cache-mode>
    <properties>
      <property name="datanucleus.storeManagerType" value="true" />
      <property name="hibernate.bytecode.use_reflection_optimizer" value="true" />
      <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
      <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/hr" />
      <property name="hibernate.connection.username" value="root" />
      <property name="hibernate.connection.password" value="123123" />
    </properties>
  </persistence-unit>
</persistence>

Here is my simple code for updating the object into database...

public void updateObj(Customer obj) throws Exception {
  EntityManager em = getEntityManager();
  try {
    em.getTransaction().begin();
    entityManager.merge(obj);
    commitTransaction();
  } catch (Exception e) {
    em.getTransaction().rollback();
    throw e;
  } finally {
    em.close();
  }
}

The following is the function for getting object list from database...

public ObjDataList getObjList(CriteriaParams cri) throws Exception {
  EntityManager em = getEntityManager();
  try {
    String l_cri = " where c.column1 like '%" + cri.getKeyword() + "%' or c.column2 like '%" + cri.getKeyword() + "%'";
    String l_searchJPQL = "select c from Customer c" + l_cri;
    List < Customer > l_entityList = em.createQuery(l_searchJPQL, Role.class)
      .setFirstResult(cri.getIndex())
      .setMaxResults(cri.getSize())
      .getResultList();

    ObjDataList l_dataList = new ObjDataList();
    l_dataList.setEntityList(l_entityList);

    if (cri.getIndex() == 0) {
      String l_countQuery = "select count(c.column1) from Customer c" + l_cri;
      l_dataList.setTotalRecord(em.createQuery(l_countQuery, Long.class).getSingleResult());
    }

    return l_dataList;
  } catch (Exception e) {
    throw e;
  } finally {
    em.close();
  }
}

Thanks

  • More details on how `commitTransaction()` & `getEntityManager()` implemented would help to understand better. – Nayan Wadekar Mar 28 '15 at 23:08
  • --getEntityManager entityManager = emFactory.crearteEntityManager(); --commitTransaction() entityManager.getTransaction().commit(); – Kaung Myat Bo Mar 29 '15 at 05:38

2 Answers2

0

If you want to bypass the cache and read from the database, you can set the cache mode to refresh.

Refresh will also update the cache with its new findings.

See here: http://docs.oracle.com/javaee/6/tutorial/doc/gkjjj.html

FMC
  • 650
  • 12
  • 31
0

This sounds more like an effect of the first level cache. Check that the part creating the list actually gets a fresh EntityManager and is not reusing an old one, which includes the (stale) 1st level cache.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348