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.InvoiceとInvoiceBaseのPersistentオブジェクトをそれぞれ取得する
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) {
}
}
}