title: Hibernate EntityManager can't find object (NoResultException), but object is in DB
body: <p>We're using a service layer class for executing hibernate entitymanager operations, like find or persist entities to our mysql database. We run an integration test (10000 times), which performs a persist to the database and in the second step, we want to find this entity and update a column ('state') of the entity. The problem is, that both operations are independent, what means:</p>
  
  <ol>
  <li>Create entity and persist</li>
  <li>Find this particular entity through a named query and update</li>
  </ol>
  
  <p>Sometimes, the entity is not found by the named query after random repeats (1000, 3500, 6000), but we see the entity is in database while debugging and getting a NoResultException.</p>
  
  <p>Here is our sample code:</p>
  
  <p>persistence.xml</p>
  
  <pre><code>&lt;persistence&gt;
      &lt;persistence-unit name="GDCT_PU" transaction-type="RESOURCE_LOCAL"&gt;
  
          &lt;provider&gt;org.hibernate.jpa.HibernatePersistenceProvider&lt;/provider&gt;
  
          &lt;!-- the JNDI data source --&gt;
          &lt;!--&lt;non-jta-data-source&gt;java:comp/env/jdbc/testDS&lt;/non-jta-data-source&gt;--&gt;
  
          &lt;class&gt;com.ikea.hrms.gdct.persistence.config.domain.Sequence&lt;/class&gt;
          &lt;class&gt;com.ikea.hrms.gdct.persistence.config.domain.Journal&lt;/class&gt;
  
          &lt;properties&gt;
          &lt;!-- if this is true, hibernate will print (to stdout) the SQL it executes,
                  so you can check it to ensure it's not doing anything crazy --&gt;
  
          &lt;!-- since most database servers have slightly different versions of the
              SQL, Hibernate needs you to choose a dialect so it knows the subtleties of
              talking to that server --&gt;
              &lt;property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/&gt;
  
              &lt;property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/DB_RU_PT"/&gt;
  
              &lt;property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/&gt;
  
              &lt;property name="hibernate.connection.username" value="dbru_pt"/&gt;
              &lt;property name="hibernate.connection.password" value="peterkloeppel1234"/&gt;
  
              &lt;property name="hibernate.connection.useUnicode" value="true" /&gt;
              &lt;property name="hibernate.connection.characterEncoding" value="UTF-8" /&gt;
              &lt;property name="hibernate.connection.release_mode" value="on_close"/&gt;
  
              &lt;!-- JDBC connection pool (use the built-in) --&gt;
              &lt;property name="hibernate.connection.pool_size" value="100" /&gt;
              &lt;property name="org.hibernate.flushMode" value="COMMIT"/&gt;
  
          &lt;!-- this tell Hibernate to update the DDL when it starts, very useful
              for development, dangerous in production --&gt;
              &lt;property name="hibernate.hbm2ddl.auto" value="create"/&gt;
          &lt;/properties&gt;
      &lt;/persistence-unit&gt;
  &lt;/persistence&gt;
  </code></pre>
  
  <p>SequenceService.java</p>
  
  <pre><code>public static synchronized Sequence findOne(String personnelAreaCode, String documentType, String documentCreationDate, int seqNumber) {
      logger.info("Find one specific Sequence.");
  
      Sequence sequence = null;
  
      try {
          checkEM();
  
          if (EMFGlobal.getInstance().getLock().tryLock(10, TimeUnit.SECONDS)) {
              logger.info("Find one: " + personnelAreaCode + "-" + documentCreationDate + "-" + seqNumber + "-" + documentType);
              Query query = em.createNamedQuery(
                      "Sequence.findOne", Sequence.class);
  
              sequence = (Sequence) query
                      .setParameter("personalAreaCode", personnelAreaCode)
                      .setParameter("documentType", documentType)
                      .setParameter("documentCreationDate", documentCreationDate)
                      .setParameter("seqNumber", seqNumber)
                      .getSingleResult();
          }
      }
      catch(NoResultException nre) {
          logger.error(nre);
      }
      catch (InterruptedException e) {
          e.printStackTrace();
      }
      catch (JDBCConnectionException jdbcConnectionExc) {
          logger.debug("Could not prepare Statement Sequence.findOne");
          jdbcConnectionExc.printStackTrace();
      }
      catch (Exception e) {
          logger.error(e);
      }
      finally {
          disconnectEntityManager();
          EMFGlobal.getInstance().getLock().unlock();
      }
  
      return sequence;
  }
  
  
  public static synchronized void persistSequence(Sequence sequence) {
      // persist with state "Created"
      try {
          Sequence tmpSequence = SequenceService.findOne(sequence.getPersonalAreaCode(), sequence.getDocumentType(), sequence.getDocumentCreationDate(), sequence.getSeqNumber());
  
          if (EMFGlobal.getInstance().getLock().tryLock(10, TimeUnit.SECONDS)) {
              checkEM();
              em.getTransaction().begin();
  
              if (tmpSequence == null) {
                  em.persist(sequence);
              } else {
                  em.merge(sequence);
              }
  
              em.flush();
              em.getTransaction().commit();
          }
      } catch (org.hibernate.PersistentObjectException e) {
          logger.debug("Persisting sequence number went wrong. Probably problems with EntityManager.", e);
      } catch (InterruptedException e) {
          logger.error(e);
      } finally {
          disconnectEntityManager();
          EMFGlobal.getInstance().getLock().unlock();
      }
  }
  
  
  private synchronized static void checkEM() {
      logger.info("Init Entity Manager.");
      if (em == null || !em.isOpen()) {
          em = EMFGlobal.getInstance().getEm();
      } else {
          logger.info("EntityManager checked. EM is open and not null!");
      }
  }
  
  /**
   * Disconnecting EntityManager used by this class.
   */
  private static synchronized void disconnectEntityManager() {
      logger.info("Disconnecting the EntityManager.");
      if (em != null) {
          em.clear();
          if (em.isOpen()) {
              em.close();
          }
          em = null;
      }
  }
  </code></pre>
  
  <p>SequenceTest.java</p>
  
  <pre><code>public void testGenerateApprove() {
      Sequence s = null;
      for (int i = 1; i &lt; 10000; i++) {
          try {
              s = SequenceNumberManager.generateNewSequence("\\021", "002", "141123");
              logger.error("During generateNewSequence for: \\021, 002, 141123");
          } catch (Exception e) {
              e.printStackTrace();
          }
  
          try {
              SequenceNumberManager.approveSequence(s);
          } catch (Exception e) {
              logger.error("During approveSequences for sequence: " + s.toString());
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>SequenceNumberManager.java</p>
  
  <pre><code>public static synchronized Sequence generateNewSequence(final String personalArea, final String form, final Date date) throws Exception {
      String personnelAreaCode = Constants.getPersonnelAreaCode().get(personalArea);
  
      String documentType = Constants.getformIdToDocType().get(form);
      if (documentType == null) {
          documentType = "";
      }
  
      SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
  
      final char separator1 = '-';
  
      final String documentCreationDate = sdf.format(date);
  
      final char separator2 = separator1;
  
      logger.info("Getting next highest sequence number.");
      final int sequenceNumber = getNextSequenceNumber(personnelAreaCode, documentType, documentCreationDate);
  
      final char separator3 = separator1;
  
      Sequence sequence = new Sequence(personnelAreaCode, separator1, documentCreationDate, separator2,
              sequenceNumber, separator3, documentType);
  
      sequence.setFormNumber(form);
  
      Sequence seq = SequenceService.findOne(sequence.getPersonalAreaCode(), sequence.getDocumentType(), sequence.getDocumentCreationDate(), sequenceNumber);
  
      if (seq == null) {
          SequenceService.persistSequence(sequence);
      } else {
          logger.error("TAKING AN OLD SEQUENCE NUMBER!!!");
          return seq;
      }
  
      return sequence;
  }
  
  
  public static synchronized void approveSequence(Sequence sequence) throws Exception {
          String sequenceStr = sequence.toString();
          // check if approved
          if (sequence.getState().equalsIgnoreCase("Created")) {
              // set state to approved
              sequence.setState("Approved");
  
              java.util.Date persistingDate = new java.util.Date();
              java.sql.Date sqlDate = new java.sql.Date(persistingDate.getTime());
              sequence.setPersistingDate(sqlDate);
  
              SequenceService.persistSequence(sequence);
  
          } else if (sequence.getState().equalsIgnoreCase("Approved")) {
              logger.error("Sequence: " + sequenceStr + " is already approved. Please generate a new Sequence number.");
              throw new Exception("Sequence: " + sequenceStr
                      + " is already approved. Please generate a new Sequence number.");
          }
  
  }
  </code></pre>
  
  <p>EMFGlobal.java</p>
  
  <pre><code>public class EMFGlobal {
      private static Logger logger = Logger.getLogger(ReportingManager.class);
  
      private static EntityManagerFactory emf;
      private EntityManager em;
      private ReentrantLock lock;
  
      public void initEntityManagerFactory() {
          logger.info("Initializing the EntityManagerFactory for persistence unit GDCT_PU");
          if(emf == null || !emf.isOpen()) {
              emf = Persistence.createEntityManagerFactory("GDCT_PU");
          }
      }
  
      public void destroyEntityManagerFactory() {
          if(emf != null) {
              if(emf.isOpen()) {
                  emf.close();
              }
              emf = null;
          }
      }
  
  
      private static EMFGlobal instance = null;
  
      private EMFGlobal() {
          initEntityManagerFactory();
      }
  
      public static EMFGlobal getInstance() {
          if (EMFGlobal.instance == null) {
              EMFGlobal.instance = new EMFGlobal();
          }
          return EMFGlobal.instance;
      }
  
      public EntityManagerFactory getEmf() {
          initEntityManagerFactory();
          return emf;
      }
  
      public EntityManager getEm() {
          if(emf == null) {
              initEntityManagerFactory();
          }
          if(em == null || !em.isOpen()) {
              em = emf.createEntityManager();
          }
          return em;
      }
  
      public Lock getLock() {
          if(lock == null) {
              lock = new ReentrantLock();
          }
          return lock;
      }
  }
  </code></pre>
  
  <p>Sequence.java</p>
  
  <pre><code>@Entity(name = "sequence")
  @NamedQueries(value = {
          @NamedQuery(name = "Sequence.findByPersonalAreaCodeAndDocumentTypeAndDocumentCreationDate",
                  query = "SELECT s FROM sequence s WHERE s.personalAreaCode = :personalAreaCode AND s.documentType = :documentType AND s.documentCreationDate = :documentCreationDate"),
          @NamedQuery(name = "Sequence.findAll",
                  query = "SELECT s FROM sequence s"),
          @NamedQuery(name = "Sequence.findOne",
                  query = "SELECT s FROM sequence s WHERE s.personalAreaCode = :personalAreaCode AND s.documentType = :documentType AND s.documentCreationDate = :documentCreationDate AND s.seqNumber = :seqNumber"),
          @NamedQuery(name = "Sequence.getNextSequenceNumber",
                  query = "SELECT s FROM sequence s WHERE s.seqNumber=(SELECT max(s.seqNumber) FROM sequence s WHERE s.personalAreaCode = :personalAreaCode AND s.documentType = :documentType AND s.documentCreationDate = :documentCreationDate) AND s.personalAreaCode = :personalAreaCode AND s.documentType = :documentType AND s.documentCreationDate = :documentCreationDate")
  })
  public class Sequence implements Serializable {
  
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private int seqId;
      private String personalAreaCode;
      @Column(nullable = false, length = 1)
      private char separator1;
      @Column(nullable = false, length = 6)
      private String documentCreationDate; // format: yyMMdd
      @Column(nullable = false, length = 1)
      private char separator2;
      @Column(nullable = false)
      private int seqNumber;
      @Column(nullable = false, length = 1)
      private char separator3;
      @Column(nullable = false)
      private String documentType;
  
      @Column(nullable = false)
      private String state;
      private Date persistingDate;
      @Column(nullable = false)
      private String formNumber;
  
  
      public Sequence() {
          // no-args constructor required by JPA spec
          // this one is protected since it shouldn't be used directly
      }
  
      /**
       * Constructs Sequence with state "Created".
       *
       * @param personalAreaCode     Personnel Area Code (PAC, e.g. RSO).
       * @param separator1           Separator between PAC and DCD.
       * @param documentCreationDate Document Creation Date (DCD).
       * @param separator2           Separator between DCD and SN.
       * @param seqNumber            Sequence count Number (SN).
       * @param separator3           Separator between SN and DT.
       * @param documentType         Document Type (DT).
       */
      public Sequence(String personalAreaCode, char separator1, String documentCreationDate, char separator2, int seqNumber, char separator3, String documentType) {
          this.personalAreaCode = personalAreaCode;
          this.separator1 = separator1;
          this.separator2 = separator2;
          this.seqNumber = seqNumber;
          this.separator3 = separator3;
          this.documentType = documentType;
          this.documentCreationDate = documentCreationDate;
          this.state = "Created";
      }
  
      public int getSeqId() {
          return seqId;
      }
  
      public void setSeqId(int seqId) {
          this.seqId = seqId;
      }
  
      public String getPersonalAreaCode() {
          return personalAreaCode;
      }
  
      public void setPersonalAreaCode(String personalAreaCode) {
          this.personalAreaCode = personalAreaCode;
      }
  
      public char getSeparator1() {
          return separator1;
      }
  
      public void setSeparator1(char separator1) {
          this.separator1 = separator1;
      }
  
      public char getSeparator2() {
          return separator2;
      }
  
      public void setSeparator2(char separator2) {
          this.separator2 = separator2;
      }
  
      public int getSeqNumber() {
          return seqNumber;
      }
  
      public void setSeqNumber(int seqNumber) {
          this.seqNumber = seqNumber;
      }
  
      public char getSeparator3() {
          return separator3;
      }
  
      public void setSeparator3(char separator3) {
          this.separator3 = separator3;
      }
  
      public String getDocumentType() {
          return documentType;
      }
  
      public void setDocumentType(String documentType) {
          this.documentType = documentType;
      }
  
      public String getDocumentCreationDate() {
          return documentCreationDate;
      }
  
      public void setDocumentCreationDate(String documentCreationDate) {
          this.documentCreationDate = documentCreationDate;
      }
  
      public String getState() {
          return state;
      }
  
      public void setState(String state) {
          this.state = state;
      }
  
      public Date getPersistingDate() {
          return persistingDate;
      }
  
      public void setPersistingDate(Date persistingDate) {
          this.persistingDate = persistingDate;
      }
  
      public String getFormNumber() {
          return formNumber;
      }
  
      public void setFormNumber(String formNumber) {
          this.formNumber = formNumber;
      }
  
      @Override
      public String toString() {
          return this.getPersonalAreaCode() + this.getSeparator1() + this.getDocumentCreationDate() + this.getSeparator2()
                  + this.getSeqNumber() + this.getSeparator3() + this.getDocumentType();
      }
  
      @Override
      public boolean equals(Object o) {
          if(o instanceof Sequence) {
              Sequence seq = (Sequence) o;
              return this.toString().equals(seq.toString());
          }
          else {
              return false;
          }
      }
  }
  </code></pre>
  
  <p>We hope someone can help us. We also tried a lot of stuff like creating the EntityManagerFactory and the EntityManager before every transaction and close it after, but it got even worse. Thanks for any help or advice.</p>