diff --git a/org.adempiere.base/src/org/compiere/model/MSession.java b/org.adempiere.base/src/org/compiere/model/MSession.java
index 8913327a2a..58bd5e6ed4 100644
--- a/org.adempiere.base/src/org/compiere/model/MSession.java
+++ b/org.adempiere.base/src/org/compiere/model/MSession.java
@@ -20,13 +20,14 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.ResultSet;
import java.util.Properties;
-import java.util.Vector;
import java.util.logging.Level;
import org.compiere.Adempiere;
import org.compiere.util.Env;
import org.compiere.util.TimeUtil;
import org.compiere.util.WebUtil;
+import org.idempiere.cache.ImmutableIntPOCache;
+import org.idempiere.cache.ImmutablePOSupport;
/**
* Session Model.
@@ -39,7 +40,7 @@ import org.compiere.util.WebUtil;
*
BF [ 1810182 ] Session lost after cache reset
* BF [ 1892156 ] MSession is not really cached
*/
-public class MSession extends X_AD_Session
+public class MSession extends X_AD_Session implements ImmutablePOSupport
{
/**
*
@@ -52,30 +53,47 @@ public class MSession extends X_AD_Session
* @param ctx context
* @param createNew create if not found
* @return session session
+ * @deprecated get (Properties ctx, boolean createNew, boolean isCache) for caching support
*/
public static MSession get (Properties ctx, boolean createNew)
+ {
+ return get(ctx, createNew, false);
+ } // get
+
+ /**
+ * Get existing or create local session
+ * @param ctx context
+ * @param createNew create if not found
+ * @param isImmutable return Immutable Session Object (from Cache)
+ * @return session session
+ */
+ public static MSession get (Properties ctx, boolean createNew, boolean isImmutable)
{
int AD_Session_ID = Env.getContextAsInt(ctx, Env.AD_SESSION_ID);
- MSession session = null;
+ MSession session = isImmutable ? s_sessions.get(ctx, AD_Session_ID, e -> new MSession(ctx, e)) : new MSession(ctx, AD_Session_ID, null);
// Try to load
- if (AD_Session_ID > 0 && s_sessions.contains(AD_Session_ID))
+ if (isImmutable && session == null && AD_Session_ID > 0)
{
session = new MSession(ctx, AD_Session_ID, null);
- if (session.get_ID() != AD_Session_ID)
+ if (session.get_ID () == AD_Session_ID)
+ {
+ s_sessions.put (AD_Session_ID, session, e -> new MSession(Env.getCtx(), e));
+ } else
{
session = null;
- s_sessions.remove(AD_Session_ID);
}
}
// Create New
if (session == null && createNew)
{
- session = new MSession (ctx, null); // local session
+ session = new MSession (ctx, (String)null); // local session
session.saveEx();
AD_Session_ID = session.getAD_Session_ID();
Env.setContext (ctx, Env.AD_SESSION_ID, AD_Session_ID);
- s_sessions.add (Integer.valueOf(AD_Session_ID));
- }
+ if(isImmutable)
+ s_sessions.put (AD_Session_ID, session, e -> new MSession(Env.getCtx(), e));
+ }
+
return session;
} // get
@@ -86,34 +104,42 @@ public class MSession extends X_AD_Session
* @param Remote_Host remote host
* @param WebSession web session
* @return session
+ * @deprecated use get (Properties ctx, String Remote_Addr, String Remote_Host, String WebSession, boolean isCache)
*/
public static MSession get (Properties ctx, String Remote_Addr, String Remote_Host, String WebSession)
+ {
+ return get(ctx, Remote_Addr, Remote_Host, WebSession, false);
+ } // get
+
+ /**
+ * Get existing or create remote session
+ * @param ctx context
+ * @param Remote_Addr remote address
+ * @param Remote_Host remote host
+ * @param WebSession web session
+ * @param isImmutable return Immutable Object (from Cache)
+ * @return session
+ */
+ public static MSession get (Properties ctx, String Remote_Addr, String Remote_Host, String WebSession, boolean isImmutable)
{
int AD_Session_ID = Env.getContextAsInt(ctx, Env.AD_SESSION_ID);
- MSession session = null;
- // Try to load
- if (AD_Session_ID > 0 && s_sessions.contains(AD_Session_ID))
- {
- session = new MSession(ctx, AD_Session_ID, null);
- if (session.get_ID() != AD_Session_ID)
- {
- session = null;
- s_sessions.remove(AD_Session_ID);
- }
- }
+ MSession session = get(ctx, false, isImmutable);
+
if (session == null)
{
session = new MSession (ctx, Remote_Addr, Remote_Host, WebSession, null); // remote session
session.saveEx();
AD_Session_ID = session.getAD_Session_ID();
Env.setContext(ctx, Env.AD_SESSION_ID, AD_Session_ID);
- s_sessions.add(Integer.valueOf(AD_Session_ID));
+ if(isImmutable)
+ s_sessions.put (AD_Session_ID, session, e -> new MSession(Env.getCtx(), e));
}
+
return session;
} // get
- /** Sessions */
- private static Vector s_sessions = new Vector<>();
+ /** Session Cache */
+ private static ImmutableIntPOCache s_sessions = new ImmutableIntPOCache(Table_Name, 20);
/**************************************************************************
@@ -193,6 +219,37 @@ public class MSession extends X_AD_Session
log.log(Level.SEVERE, "No Local Host", e);
}
} // MSession
+
+ /**
+ *
+ * @param copy
+ */
+ public MSession(MSession copy)
+ {
+ this(Env.getCtx(), copy);
+ }
+
+ /**
+ *
+ * @param ctx
+ * @param copy
+ */
+ public MSession(Properties ctx, MSession copy)
+ {
+ this(ctx, copy, (String) null);
+ }
+
+ /**
+ *
+ * @param ctx
+ * @param copy
+ * @param trxName
+ */
+ public MSession(Properties ctx, MSession copy, String trxName)
+ {
+ this(ctx, 0, trxName);
+ copyPO(copy);
+ }
/** Web Store Session */
private boolean m_webStoreSession = false;
@@ -330,5 +387,14 @@ public class MSession extends X_AD_Session
public static int getCachedSessionCount() {
return s_sessions.size()-1;
}
+
+ @Override
+ public MSession markImmutable() {
+ if (is_Immutable())
+ return this;
+
+ makeImmutable();
+ return this;
+ }
} // MSession
diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java
index 38c43e15c4..3749c39411 100644
--- a/org.adempiere.base/src/org/compiere/model/PO.java
+++ b/org.adempiere.base/src/org/compiere/model/PO.java
@@ -2661,7 +2661,7 @@ public abstract class PO
lobReset();
// Change Log
- MSession session = MSession.get (p_ctx, false);
+ MSession session = MSession.get (p_ctx, false, true);
if (session == null)
log.fine("No Session found");
int AD_ChangeLog_ID = 0;
@@ -3123,7 +3123,7 @@ public abstract class PO
lobReset();
// Change Log
- MSession session = MSession.get (p_ctx, false);
+ MSession session = MSession.get (p_ctx, false, true);
if (session == null)
log.fine("No Session found");
int AD_ChangeLog_ID = 0;
@@ -3719,7 +3719,7 @@ public abstract class PO
if( p_info.isChangeLog())
{
// Change Log
- MSession session = MSession.get (p_ctx, false);
+ MSession session = MSession.get (p_ctx, false, true);
if (session == null)
log.fine("No Session found");
else if (m_IDs.length == 1)
diff --git a/org.adempiere.base/src/org/compiere/process/ProcessInfo.java b/org.adempiere.base/src/org/compiere/process/ProcessInfo.java
index d41d768830..ddc15ce628 100644
--- a/org.adempiere.base/src/org/compiere/process/ProcessInfo.java
+++ b/org.adempiere.base/src/org/compiere/process/ProcessInfo.java
@@ -912,7 +912,7 @@ public class ProcessInfo implements Serializable
}
private Timestamp getLastServerRebootDate() {
- MSession currentSession = MSession.get(Env.getCtx(), false);
+ MSession currentSession = MSession.get(Env.getCtx(), false, true);
if (currentSession == null)
return null;
diff --git a/org.adempiere.base/src/org/compiere/util/Env.java b/org.adempiere.base/src/org/compiere/util/Env.java
index 682c66b37c..6f30bc2300 100644
--- a/org.adempiere.base/src/org/compiere/util/Env.java
+++ b/org.adempiere.base/src/org/compiere/util/Env.java
@@ -176,7 +176,7 @@ public final class Env
//hengsin, avoid unncessary query of session when exit without log in
if (DB.isConnected(false)) {
// End Session
- MSession session = MSession.get(Env.getCtx(), false); // finish
+ MSession session = MSession.get(Env.getCtx(), false, false); // finish
if (session != null)
session.logout();
}
@@ -195,7 +195,7 @@ public final class Env
public static void logout()
{
// End Session
- MSession session = MSession.get(Env.getCtx(), false); // finish
+ MSession session = MSession.get(Env.getCtx(), false, false); // finish
if (session != null)
session.logout();
//
diff --git a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/AdempiereActivator.java b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/AdempiereActivator.java
index e0bb67f63d..6c9a2f7b92 100644
--- a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/AdempiereActivator.java
+++ b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/AdempiereActivator.java
@@ -98,7 +98,7 @@ public class AdempiereActivator extends AbstractActivator {
MSession localSession = null;
//Create Session to be able to create records in AD_ChangeLog
if (Env.getContextAsInt(Env.getCtx(), Env.AD_SESSION_ID) <= 0) {
- localSession = MSession.get(Env.getCtx(), true);
+ localSession = MSession.get(Env.getCtx(), true, false);
localSession.setWebSession("AdempiereActivator");
localSession.saveEx();
}
diff --git a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/Incremental2PackActivator.java b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/Incremental2PackActivator.java
index 9d0afc6e03..19a49a8be2 100644
--- a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/Incremental2PackActivator.java
+++ b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/Incremental2PackActivator.java
@@ -212,7 +212,7 @@ public class Incremental2PackActivator extends AbstractActivator {
MSession localSession = null;
//Create Session to be able to create records in AD_ChangeLog
if (Env.getContextAsInt(Env.getCtx(), Env.AD_SESSION_ID) <= 0) {
- localSession = MSession.get(Env.getCtx(), true);
+ localSession = MSession.get(Env.getCtx(), true, false);
localSession.setWebSession("Incremental2PackActivator");
localSession.saveEx();
}
diff --git a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/PackInApplicationActivator.java b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/PackInApplicationActivator.java
index 2973247ccf..3aef44fd35 100644
--- a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/PackInApplicationActivator.java
+++ b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/PackInApplicationActivator.java
@@ -101,7 +101,7 @@ public class PackInApplicationActivator extends AbstractActivator{
if (getDBLock()) {
//Create Session to be able to create records in AD_ChangeLog
if (Env.getContextAsInt(Env.getCtx(), Env.AD_SESSION_ID) <= 0) {
- localSession = MSession.get(Env.getCtx(), true);
+ localSession = MSession.get(Env.getCtx(), true, false);
localSession.setWebSession("PackInApplicationActivator");
localSession.saveEx();
}
diff --git a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/Version2PackActivator.java b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/Version2PackActivator.java
index 9de8767664..fdec2d118f 100644
--- a/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/Version2PackActivator.java
+++ b/org.adempiere.plugin.utils/src/org/adempiere/plugin/utils/Version2PackActivator.java
@@ -151,7 +151,7 @@ public class Version2PackActivator extends AbstractActivator{
if (getDBLock()) {
//Create Session to be able to create records in AD_ChangeLog
if (Env.getContextAsInt(Env.getCtx(), Env.AD_SESSION_ID) <= 0) {
- localSession = MSession.get(Env.getCtx(), true);
+ localSession = MSession.get(Env.getCtx(), true, false);
localSession.setWebSession("Version2PackActivator");
localSession.saveEx();
}
diff --git a/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServerMgr.java b/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServerMgr.java
index 75979de059..9942728416 100644
--- a/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServerMgr.java
+++ b/org.adempiere.server/src/main/server/org/compiere/server/AdempiereServerMgr.java
@@ -119,7 +119,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer, IWeb
String x_Forward_IP = Executions.getCurrent().getHeader("X-Forwarded-For");
MSession mSession = MSession.get (ctx, x_Forward_IP!=null ? x_Forward_IP : Executions.getCurrent().getRemoteAddr(),
- Executions.getCurrent().getRemoteHost(), httpSess.getId() );
+ Executions.getCurrent().getRemoteHost(), httpSess.getId(), false );
if (clientInfo.userAgent != null) {
mSession.setDescription(mSession.getDescription() + "\n" + clientInfo.toString());
mSession.saveEx();
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java
index 33292d2c81..01285036d9 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java
@@ -211,7 +211,7 @@ public final class AEnv
}
windowCache.remove(sessionID);
// End Session
- MSession session = MSession.get(Env.getCtx(), false); // finish
+ MSession session = MSession.get(Env.getCtx(), false, false); // finish
if (session != null)
session.logout();
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java
index 0f592252b6..7c10b8f498 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java
@@ -265,7 +265,7 @@ public class SessionContextListener implements ExecutionInit,
}
}
- MSession mSession = MSession.get(Env.getCtx(), false);
+ MSession mSession = MSession.get(Env.getCtx(), false, false);
if(mSession!=null && !mSession.isProcessed()) {
mSession.setProcessed(true);
@@ -318,7 +318,7 @@ public class SessionContextListener implements ExecutionInit,
{
setupExecutionContextFromSession(Executions.getCurrent());
}
- MSession mSession = MSession.get(Env.getCtx(), false);
+ MSession mSession = MSession.get(Env.getCtx(), false, false);
if(mSession!=null){
if (mSession.isProcessed()) {
mSession.setProcessed(false);
diff --git a/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/CompiereService.java b/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/CompiereService.java
index 41cc9f1610..0bc98d6c08 100644
--- a/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/CompiereService.java
+++ b/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/CompiereService.java
@@ -288,10 +288,10 @@ public class CompiereService {
Env.setContext(getCtx(), Env.LANGUAGE, m_language.getAD_Language());
// Create session
- MSession session = MSession.get (getCtx(), false);
+ MSession session = MSession.get (getCtx(), false, false);
if (session == null){
log.fine("No Session found");
- session = MSession.get (getCtx(), true);
+ session = MSession.get (getCtx(), true, false);
}
session.setWebSession("WebService");