IDEMPIERE-5996 Record Access is not being updated when a new record is added (#2194)

* IDEMPIERE-5996 Record Access is not being updated when a new record is added

* - correct CacheMgt.getElementCount

* - revert correction of CacheMgt.getElementCount

* - reset changes on MRole

* - implemnt suggestion from Heng Sin about validation of cache size

* - simpler approach, make the default role a cache instead of context

* - remove unnecessary code

* - implement suggestion from Heng Sin - keep instance of validation

* - revert changes on MRole to try a different approach

* - Implement approach suggested by Heng Sin - reset default role when is not in cache
This commit is contained in:
Carlos Ruiz 2024-01-22 03:57:13 +01:00
parent 2dadd8fa97
commit fceb0614a5
14 changed files with 479 additions and 62 deletions

View File

@ -21,6 +21,8 @@ import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Level;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
import org.compiere.util.DB;
import org.compiere.util.Msg;
@ -32,12 +34,12 @@ import org.compiere.util.Msg;
*/
public class MColumnAccess extends X_AD_Column_Access
{
/**
* generated serial id
/**
*
*/
private static final long serialVersionUID = -2362624234744824977L;
private static final long serialVersionUID = -4824730344123047467L;
/**
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Column_Access_UU UUID key
@ -169,4 +171,29 @@ public class MColumnAccess extends X_AD_Column_Access
return m_columnName;
} // getColumnName
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MColumnAccess

View File

@ -28,13 +28,16 @@ package org.compiere.model;
import java.sql.ResultSet;
import java.util.Properties;
public class MDocumentActionAccess extends X_AD_Document_Action_Access {
/**
* generated serial id
*/
private static final long serialVersionUID = -2036011342206732816L;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
/**
public class MDocumentActionAccess extends X_AD_Document_Action_Access {
/**
*
*/
private static final long serialVersionUID = -7387829651626682825L;
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Document_Action_Access_UU UUID key
@ -68,4 +71,29 @@ public class MDocumentActionAccess extends X_AD_Document_Action_Access {
super(ctx, rs, trxName);
} // MDocumentActionAccess
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MDocumentActionAccess

View File

@ -19,6 +19,8 @@ package org.compiere.model;
import java.sql.ResultSet;
import java.util.Properties;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
import org.compiere.util.Util;
/**
@ -29,12 +31,12 @@ import org.compiere.util.Util;
*/
public class MFormAccess extends X_AD_Form_Access
{
/**
* generated serial id
/**
*
*/
private static final long serialVersionUID = 7818255846843514899L;
private static final long serialVersionUID = 904675604033766598L;
/**
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Form_Access_UU UUID key
@ -93,5 +95,29 @@ public class MFormAccess extends X_AD_Form_Access
setAD_Role_ID (AD_Role_ID);
} // MFormAccess
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MFormAccess

View File

@ -24,18 +24,20 @@ package org.compiere.model;
import java.sql.ResultSet;
import java.util.Properties;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
/**
* @author hengsin
*
*/
public class MInfoWindowAccess extends X_AD_InfoWindow_Access {
/**
*
*/
private static final long serialVersionUID = -648483177632575172L;
/**
* generated serial id
*/
private static final long serialVersionUID = -5134731157350014858L;
/**
* UUID based Constructor
* @param ctx Context
* @param AD_InfoWindow_Access_UU UUID key
@ -79,4 +81,29 @@ public class MInfoWindowAccess extends X_AD_InfoWindow_Access {
setAD_Role_ID (AD_Role_ID);
} // MInfoWindowAccess
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
}

View File

@ -19,6 +19,8 @@ package org.compiere.model;
import java.sql.ResultSet;
import java.util.Properties;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
import org.compiere.util.Util;
/**
@ -29,12 +31,12 @@ import org.compiere.util.Util;
*/
public class MProcessAccess extends X_AD_Process_Access
{
/**
* generated serial id
/**
*
*/
private static final long serialVersionUID = -2468108979800832171L;
private static final long serialVersionUID = 7698694345394848144L;
/**
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Process_Access_UU UUID key
@ -93,4 +95,29 @@ public class MProcessAccess extends X_AD_Process_Access
setAD_Role_ID (AD_Role_ID);
} // MProcessAccess
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MProcessAccess

View File

@ -34,12 +34,12 @@ import org.compiere.util.Msg;
*/
public class MRecordAccess extends X_AD_Record_Access
{
/**
/**
*
*/
private static final long serialVersionUID = -3608241027957009608L;
private static final long serialVersionUID = -6463810251202651132L;
/**
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Record_Access_UU UUID key
@ -298,12 +298,21 @@ public class MRecordAccess extends X_AD_Record_Access
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (!success)
return success;
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MRecordAccess

View File

@ -64,10 +64,10 @@ import org.idempiere.cache.POCopyCache;
*/
public final class MRole extends X_AD_Role implements ImmutablePOSupport
{
/**
* generated serial id
/**
*
*/
private static final long serialVersionUID = -8937680640915708588L;
private static final long serialVersionUID = 7266911648463503849L;
/**
* Get role for current session/context
@ -95,7 +95,7 @@ public final class MRole extends X_AD_Role implements ImmutablePOSupport
int AD_Role_ID = Env.getContextAsInt(ctx, Env.AD_ROLE_ID);
int AD_User_ID = Env.getContextAsInt(ctx, Env.AD_USER_ID);
MRole defaultRole = getDefaultRole();
MRole defaultRole = getDefaultRole(ctx, AD_Role_ID, AD_User_ID);
if (reload || defaultRole == null)
{
defaultRole = get (ctx, AD_Role_ID, AD_User_ID, reload);
@ -124,7 +124,24 @@ public final class MRole extends X_AD_Role implements ImmutablePOSupport
* @return MRole
*/
private static MRole getDefaultRole() {
return (MRole) Env.getCtx().get(ROLE_KEY);
return getDefaultRole(Env.getCtx(), Env.getAD_Role_ID(Env.getCtx()), Env.getAD_User_ID(Env.getCtx()));
}
/**
* Get role for current session/context
* @param ctx
* @param AD_Role_ID
* @param AD_User_ID
* @return MRole
*/
private static MRole getDefaultRole(Properties ctx, int AD_Role_ID, int AD_User_ID) {
MRole role = (MRole) ctx.get(ROLE_KEY);
String key = AD_Role_ID + "_" + AD_User_ID;
if (! s_roles.containsKey(key)) {
ctx.remove(ROLE_KEY);
role = null;
}
return role;
}
/**
@ -467,11 +484,7 @@ public final class MRole extends X_AD_Role implements ImmutablePOSupport
//
else if (is_ValueChanged("UserLevel"))
updateAccessRecords();
// Default Role changed
if (getDefaultRole() != null
&& getDefaultRole().get_ID() == get_ID())
setDefaultRole(this);
return success;
} // afterSave

View File

@ -30,6 +30,8 @@ import java.util.Properties;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
import org.compiere.util.DB;
/**
@ -38,12 +40,12 @@ import org.compiere.util.DB;
*/
public class MRoleIncluded extends X_AD_Role_Included
{
/**
* generated serial id
*/
private static final long serialVersionUID = -3284165639631581484L;
/**
*
*/
private static final long serialVersionUID = 4101136698198494931L;
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Role_Included_UU UUID key
@ -83,6 +85,12 @@ public class MRoleIncluded extends X_AD_Role_Included
return true;
}
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success)
{
@ -105,6 +113,7 @@ public class MRoleIncluded extends X_AD_Role_Included
throw new AdempiereException("Loop has detected "+roles);
}
}
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
//
return true;
}
@ -174,4 +183,16 @@ public class MRoleIncluded extends X_AD_Role_Included
return false;
}
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
}

View File

@ -22,7 +22,9 @@ import java.util.ArrayList;
import java.util.Properties;
import java.util.logging.Level;
import org.compiere.Adempiere;
import org.compiere.util.CLogger;
import org.compiere.util.CacheMgt;
import org.compiere.util.DB;
import org.compiere.util.Msg;
import org.compiere.util.Util;
@ -36,9 +38,9 @@ import org.compiere.util.Util;
public class MRoleOrgAccess extends X_AD_Role_OrgAccess
{
/**
* generated serial id
*
*/
private static final long serialVersionUID = 4664267788838719168L;
private static final long serialVersionUID = -3476937107774004286L;
/**
* Get Organizational Access of Role
@ -281,4 +283,29 @@ public class MRoleOrgAccess extends X_AD_Role_OrgAccess
return m_orgName;
} // getOrgName
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MRoleOrgAccess

View File

@ -21,6 +21,8 @@ import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Level;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
import org.compiere.util.DB;
import org.compiere.util.Msg;
@ -31,12 +33,12 @@ import org.compiere.util.Msg;
*/
public class MTableAccess extends X_AD_Table_Access
{
/**
* generated serial id
/**
*
*/
private static final long serialVersionUID = -3747261579266442904L;
private static final long serialVersionUID = -4075182397260458949L;
/**
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Table_Access_UU UUID key
@ -154,4 +156,29 @@ public class MTableAccess extends X_AD_Table_Access
return m_tableName;
} // getTableName
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MTableAccess

View File

@ -0,0 +1,132 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Carlos Ruiz - globalqss - bxservice *
**********************************************************************/
/**
*
* @author Carlos Ruiz - globalqss - bxservice
*
*/
package org.compiere.model;
import java.sql.ResultSet;
import java.util.Properties;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
import org.compiere.util.Util;
public class MTaskAccess extends X_AD_Task_Access
{
/**
*
*/
private static final long serialVersionUID = -2652529697830798536L;
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Task_Access_UU UUID key
* @param trxName Transaction
*/
public MTaskAccess(Properties ctx, String AD_Task_Access_UU, String trxName) {
super(ctx, AD_Task_Access_UU, trxName);
if (Util.isEmpty(AD_Task_Access_UU))
setInitialDefaults();
}
/**
* Standard Constructor
* @param ctx context
* @param ignored id=0
* @param trxName trx
*/
public MTaskAccess (Properties ctx, int ignored, String trxName)
{
super(ctx, 0, trxName);
if (ignored == 0)
setInitialDefaults();
else
throw new IllegalArgumentException("Multi-Key");
} // MTaskAccess
/**
* Set the initial defaults for a new record
*/
private void setInitialDefaults() {
setIsReadWrite (true);
}
/**
* Load Constructor
* @param ctx context
* @param rs result set
* @param trxName transaction
*/
public MTaskAccess (Properties ctx, ResultSet rs, String trxName)
{
super(ctx, rs, trxName);
} // MTaskAccess
/**
* Parent Constructor
* @param parent parent
* @param AD_Role_ID role id
*/
public MTaskAccess (MTask parent, int AD_Role_ID)
{
super (parent.getCtx(), 0, parent.get_TrxName());
MRole role = MRole.get(parent.getCtx(), AD_Role_ID);
setClientOrg(role);
setAD_Task_ID(parent.getAD_Task_ID());
setAD_Role_ID (AD_Role_ID);
} // MTaskAccess
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MTaskAccess

View File

@ -19,6 +19,8 @@ package org.compiere.model;
import java.sql.ResultSet;
import java.util.Properties;
import org.compiere.Adempiere;
import org.compiere.util.CacheMgt;
import org.compiere.util.Util;
@ -30,13 +32,12 @@ import org.compiere.util.Util;
*/
public class MWindowAccess extends X_AD_Window_Access
{
/**
/**
*
*/
private static final long serialVersionUID = -1236781018671637481L;
private static final long serialVersionUID = 7056606424817652079L;
/**
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Window_Access_UU UUID key
@ -95,4 +96,29 @@ public class MWindowAccess extends X_AD_Window_Access
setAD_Role_ID (AD_Role_ID);
} // MWindowAccess
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MWindowAccess

View File

@ -307,7 +307,7 @@ public class CacheMgt
CacheInterface[] instances = getInstancesAsArray();
for (CacheInterface stored : instances)
{
if (stored != null && stored instanceof CCache)
if (stored != null && stored instanceof CCache && stored.size() > 0)
{
CCache<?, ?> cc = (CCache<?, ?>)stored;
if (cc.getTableName() != null && cc.getTableName().startsWith(tableName)) // reset lines/dependent too

View File

@ -19,8 +19,10 @@ package org.compiere.wf;
import java.sql.ResultSet;
import java.util.Properties;
import org.compiere.Adempiere;
import org.compiere.model.MRole;
import org.compiere.model.X_AD_Workflow_Access;
import org.compiere.util.CacheMgt;
import org.compiere.util.Util;
/**
@ -31,12 +33,12 @@ import org.compiere.util.Util;
*/
public class MWorkflowAccess extends X_AD_Workflow_Access
{
/**
* generated serial id
/**
*
*/
private static final long serialVersionUID = 2598861248782340850L;
private static final long serialVersionUID = -4496940668011091889L;
/**
/**
* UUID based Constructor
* @param ctx Context
* @param AD_Workflow_Access_UU UUID key
@ -97,4 +99,29 @@ public class MWorkflowAccess extends X_AD_Workflow_Access
setAD_Role_ID (AD_Role_ID);
} // MWorkflowAccess
/**
* After Save
* @param newRecord new
* @param success success
* @return success
*/
@Override
protected boolean afterSave(boolean newRecord, boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
} // afterSave
/**
* After Delete
* @param success success
* @return success
*/
@Override
protected boolean afterDelete(boolean success) {
if (success)
Adempiere.getThreadPoolExecutor().submit(() -> CacheMgt.get().reset(MRole.Table_Name, getAD_Role_ID()));
return success;
}
} // MWorkflowAccess