public void update2(Invoice invoice) {

    PersistenceManager pm = PMF.get().getPersistenceManager();

    FieldMapper fieldMapper = new FieldMapper();

    Transaction tx = pm.currentTransaction();

    int cntRetry = 3;

 

    try {

     for (int r = 0; r < cntRetry; r++) {

       try {

        

         tx.begin();

         if (invoice != null) {

 

           try {

            String invoiceNo = invoice.getInvoiceNo();

            long invoiceId = invoice.getId();

 

            // 1.InvoiceInvoiceBasePersistentオブジェクトをそれぞれ取得する

            Key keyInvoice = keyUtils.getChildKey(Invoice.class, invoiceNo);

            Invoice invoicePersistent = pm.getObjectById(Invoice.class, keyInvoice);

            InvoiceBase invoiceBasePersistent = pm.getObjectById(InvoiceBase.class, keyUtils.getBaseKeyBuilder().getKey());

 

            // リビジョンのカウントアップで使用する

            long revisionTarget = invoicePersistent.getRevision();

           

            // 業務アプリによる楽観的ロック

            if (revisionTarget != invoice.getRevision()) {

              throw new ConcurrentModificationException("Optimistic lock!");

            } else {

             

              // 2.クライアントからのリクエストデータのうち更新があったものだけをinvoicePersistentに反映させる

              fieldMapper.setValue(invoice, invoicePersistent);

 

              // 3.Revisionを更新

              invoicePersistent.setRevision(++revisionTarget);

 

              // 4.invoiceからinvoiceSource(1品一葉)を取得する。orderIdの最大値を更新するためにinvoiceBasePersistentも渡す。

              Invoice invoiceSource = getInvoiceSource(invoice, invoiceBasePersistent);

 

              // 5.InvoiceSource子要素のorderが存在していれば更新する。新規であればmakepersistentする。

              for(Order order:invoiceSource.getOrder()) {

                try {

                  Order orderPersistent = (Order) pm.getObjectById(Order.class, order.getKey());

                  fieldMapper.setValue(order, orderPersistent);

                } catch (JDOObjectNotFoundException e) {

                  pm.makePersistent(order);

                }

              }

            }

 

           } catch (JDOObjectNotFoundException e) {

            throw e;

           }

         }

        

         tx.commit();

         break;

       } catch (JDOCanRetryException e) {

         if (r == (cntRetry - 1)) {

           throw e;

         }

         try {

           tx.rollback();

         } catch (Throwable ee) {

         }

       } catch (JDOException e) {

         throw e;

       } catch (ConcurrentModificationException e) {

         throw e;

       }

     } //  for loop

    } finally {

     if (tx.isActive()) {

       try {

         tx.rollback();

       } catch (Throwable e) {

       }

     }

     try {

       pm.close();

     } catch (Throwable e) {

     }

    }

  }