Fixes issue 41215:Error using FIN_Utility.getDocumentNo in an event handler
authorArmaignac <collazoandy4@gmail.com>
Wed, 31 Jul 2019 12:46:44 +0200
changeset 36425 89ffba6ba6bf
parent 36424 fec13e3f3e07
child 36426 a4ac557d0271
Fixes issue 41215:Error using FIN_Utility.getDocumentNo in an event handler

An error occurs when FIN_Utility.getDocumentNo is called for a sequence that is
referenced in the entity being saved. When this is done, an NPE will happen in hibernate.

The problem is related to the call of lockSequence(seq) in getDocumentNo.
The specific problem is OBDal.getInstance().getSession().evict(seq)

The evict call was removed and also some code refactor was done
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java	Thu Aug 08 05:24:53 2019 +0000
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java	Wed Jul 31 12:46:44 2019 +0200
@@ -368,31 +368,24 @@
   }
 
   public static String getDocumentNo(boolean updateNext, Sequence seqParam) {
-    Sequence seq = seqParam;
-    if (seq != null) {
-      if (updateNext) {
-        // We lock the sequence with a select for update to avoid duplicates
-        seq = lockSequence(seq);
-      }
-      StringBuilder nextDocNumber = new StringBuilder();
-      if (seq.getPrefix() != null) {
-        nextDocNumber.append(seq.getPrefix());
-      }
-      nextDocNumber.append(seq.getNextAssignedNumber().toString());
-      if (seq.getSuffix() != null) {
-        nextDocNumber.append(seq.getSuffix());
-      }
-      if (updateNext) {
-        seq.setNextAssignedNumber(seq.getNextAssignedNumber() + seq.getIncrementBy());
-        OBDal.getInstance().save(seq);
-        // OBDal.getInstance().flush();
-      }
-      return nextDocNumber.toString();
+    if (seqParam == null) {
+      return null;
     }
-    return null;
+    Sequence seq = getSequenceAndLockIfUpdateNext(updateNext, seqParam);
+    return getNextDocNumberAndIncrementSeqIfUpdateNext(updateNext, seq);
+
   }
 
-  private static Sequence lockSequence(Sequence seq) {
+  private static Sequence getSequenceAndLockIfUpdateNext(final boolean updateNext,
+      final Sequence seqParam) {
+    if (updateNext) {
+      // We lock the sequence with a select for update to avoid duplicates
+      return lockSequence(seqParam.getId());
+    }
+    return seqParam;
+  }
+
+  private static Sequence lockSequence(String sequenceId) {
     // @formatter:off
     final String where = ""
         + "select s "
@@ -401,13 +394,35 @@
     // @formatter:on
     final Session session = OBDal.getInstance().getSession();
     final Query<Sequence> query = session.createQuery(where, Sequence.class);
-    query.setParameter("id", seq.getId());
+    query.setParameter("id", sequenceId);
     query.setMaxResults(1);
     query.setLockOptions(LockOptions.UPGRADE);
-    OBDal.getInstance().getSession().evict(seq);
     return query.uniqueResult();
   }
 
+  private static String getNextDocNumberAndIncrementSeqIfUpdateNext(final boolean updateNext,
+      final Sequence seq) {
+    final StringBuilder nextDocNumber = new StringBuilder();
+    if (seq.getPrefix() != null) {
+      nextDocNumber.append(seq.getPrefix());
+    }
+    nextDocNumber.append(seq.getNextAssignedNumber().toString());
+    if (seq.getSuffix() != null) {
+      nextDocNumber.append(seq.getSuffix());
+    }
+
+    incrementSeqIfUpdateNext(updateNext, seq);
+
+    return nextDocNumber.toString();
+  }
+
+  private static void incrementSeqIfUpdateNext(final boolean updateNext, final Sequence seq) {
+    if (updateNext) {
+      seq.setNextAssignedNumber(seq.getNextAssignedNumber() + seq.getIncrementBy());
+      OBDal.getInstance().save(seq);
+    }
+  }
+
   /**
    * Returns the next sequence number of the Document Type defined for the Organization and document
    * category. The current number of the sequence is also updated.