diff --git a/org.adempiere.base/src/org/compiere/print/MPrintFormat.java b/org.adempiere.base/src/org/compiere/print/MPrintFormat.java index c8be684937..03491e4115 100644 --- a/org.adempiere.base/src/org/compiere/print/MPrintFormat.java +++ b/org.adempiere.base/src/org/compiere/print/MPrintFormat.java @@ -46,7 +46,7 @@ import org.compiere.util.KeyNamePair; import org.compiere.util.Language; import org.compiere.util.Msg; import org.compiere.util.Util; -import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOCache; import org.idempiere.cache.ImmutablePOSupport; /** @@ -61,7 +61,7 @@ public class MPrintFormat extends X_AD_PrintFormat implements ImmutablePOSupport /** * */ - private static final long serialVersionUID = -5693788724825608611L; + private static final long serialVersionUID = 7542581302442072662L; /** * Public Constructor. @@ -1153,7 +1153,44 @@ public class MPrintFormat extends X_AD_PrintFormat implements ImmutablePOSupport } /** Cached Formats */ - static private ImmutableIntPOCache s_formats = new ImmutableIntPOCache(Table_Name, 30); + static private ImmutablePOCache s_formats = new ImmutablePOCache(Table_Name, 30) { + private static final long serialVersionUID = 2428566381289874703L; + + @Override + public int reset(int recordId) { + if (recordId <= 0) + return reset(); + + if (cache.isEmpty() && nullList.isEmpty()) + return 0; + + StringBuilder key = new StringBuilder() + .append(recordId).append("|"); + int removed = 0; + if (!nullList.isEmpty()) { + String[] nullKeys = nullList.toArray(new String[0]); + for(String nullKey : nullKeys) { + if (nullKey.startsWith(key.toString())) { + if (nullList.remove(nullKey)) + removed++; + } + } + } + + if (!cache.isEmpty()) { + String[] cacheKeys = cache.keySet().toArray(new String[0]); + for(String cacheKey : cacheKeys) { + if (cacheKey.startsWith(key.toString())) { + MPrintFormat v = cache.remove(cacheKey); + if (v != null) + removed++; + } + } + } + return removed; + } + + }; /** * Get Format from cache (immutable) @@ -1174,16 +1211,18 @@ public class MPrintFormat extends X_AD_PrintFormat implements ImmutablePOSupport */ static public MPrintFormat get (Properties ctx, int AD_PrintFormat_ID, boolean readFromDisk) { - Integer key = Integer.valueOf(AD_PrintFormat_ID); + StringBuilder key = new StringBuilder() + .append(AD_PrintFormat_ID).append("|") + .append(MRole.getDefault().getAD_Role_ID()); MPrintFormat pf = null; if (!readFromDisk) - pf = s_formats.get(ctx, key, e -> new MPrintFormat(ctx, e)); + pf = s_formats.get(ctx, key.toString(), e -> new MPrintFormat(ctx, e)); if (pf == null) { pf = new MPrintFormat (ctx, AD_PrintFormat_ID, (String)null); if (pf.get_ID() == AD_PrintFormat_ID) { - s_formats.put(key, pf, e -> new MPrintFormat(Env.getCtx(), e)); + s_formats.put(key.toString(), pf, e -> new MPrintFormat(Env.getCtx(), e)); return pf; } return null; @@ -1235,8 +1274,10 @@ public class MPrintFormat extends X_AD_PrintFormat implements ImmutablePOSupport */ static public void deleteFromCache (int AD_PrintFormat_ID) { - Integer key = Integer.valueOf(AD_PrintFormat_ID); - s_formats.put(key, null); + StringBuilder key = new StringBuilder() + .append(AD_PrintFormat_ID).append("|") + .append(MRole.getDefault().getAD_Role_ID()); + s_formats.put(key.toString(), null); } // deleteFromCache //begin vpj-cd e-evolution diff --git a/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java b/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java index 68c6d6b484..624a4e539c 100644 --- a/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java +++ b/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java @@ -97,6 +97,7 @@ import org.compiere.model.PaymentProcessor; import org.compiere.model.StandardTaxProvider; import org.compiere.model.X_C_AddressValidationCfg; import org.compiere.model.X_C_TaxProviderCfg; +import org.compiere.print.MPrintFormat; import org.compiere.process.BPartnerValidate; import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; @@ -127,6 +128,9 @@ import org.junit.jupiter.api.Test; */ public class CacheTest extends AbstractTestCase { + private static final int ORDER_HEADER_PRINT_FORMAT_ID = 118; + private static final int SHIPMENT_HEADER_PRINT_FORMAT_ID = 122; + public CacheTest() { } @@ -702,4 +706,33 @@ public class CacheTest extends AbstractTestCase { } return null; } + + @Test + public void testPrintFormatCacheReset() { + MPrintFormat cache = MPrintFormat.get(ORDER_HEADER_PRINT_FORMAT_ID); + String description = cache.getDescription(); + MPrintFormat cache1 = MPrintFormat.get(SHIPMENT_HEADER_PRINT_FORMAT_ID); + MPrintFormat update = new MPrintFormat(Env.getCtx(), cache.get_ID(), null); + try { + update.setDescription(update.getAD_PrintFormat_UU()); + update.saveEx(); + + //wait for async cache reset + try { + Thread.sleep(500); + } catch (InterruptedException e) { + } + + cache = MPrintFormat.get(ORDER_HEADER_PRINT_FORMAT_ID); + assertEquals(update.getDescription(), cache.getDescription(), "Expected cache reset doesn't happens"); + + //shipment header shouldn't reload since only order header have been updated + cache = MPrintFormat.get(SHIPMENT_HEADER_PRINT_FORMAT_ID); + assertTrue(cache == cache1, "Unexpected cache reset for print format record that's not being updated"); + } finally { + update.load((String)null); + update.setDescription(description); + update.saveEx(); + } + } }