IDEMPIERE-1146 + IDEMPIERE-3234 / Centralized ID not working with na… (#44)
* IDEMPIERE-1146 + IDEMPIERE-3234 / Centralized ID not working with native sequence enabled / PROJECT_ID_USE_CENTRALIZED_ID should take priority higher than SYSTEM_NATIVE_SEQUENCE * IDEMPIERE-1146 + IDEMPIERE-3234 improve performance not reading MTable and Columns but just a cache list of tables with EntityType column * IDEMPIERE-1146 + IDEMPIERE-3234 Remove deprecation as the method is now capable of managin all cases
This commit is contained in:
parent
a84c1eac2f
commit
1f3a83c96e
|
@ -28,6 +28,7 @@ import java.text.DecimalFormat;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
@ -35,6 +36,7 @@ import java.util.logging.Level;
|
|||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.exceptions.DBException;
|
||||
import org.compiere.db.CConnection;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.CLogMgt;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
|
@ -54,18 +56,12 @@ public class MSequence extends X_AD_Sequence
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -2215317912000946608L;
|
||||
|
||||
/** Log Level for Next ID Call */
|
||||
private static final Level LOGLEVEL = Level.ALL;
|
||||
private static final long serialVersionUID = -750059366190164777L;
|
||||
|
||||
private static final int QUERY_TIME_OUT = 30;
|
||||
|
||||
private static final String NoYearNorMonth = "-";
|
||||
|
||||
/**
|
||||
* @deprecated please use DB.getNextID (int, String, String)
|
||||
*/
|
||||
public static int getNextID (int AD_Client_ID, String TableName)
|
||||
{
|
||||
return getNextID(AD_Client_ID, TableName, null);
|
||||
|
@ -76,23 +72,15 @@ public class MSequence extends X_AD_Sequence
|
|||
* Get next number for Key column = 0 is Error.
|
||||
* @param AD_Client_ID client
|
||||
* @param TableName table name
|
||||
* @param trxName deprecated (NOT USED!!)
|
||||
* @param trxName
|
||||
* @return next no or (-1=not found, -2=error)
|
||||
*
|
||||
* WARNING!! This method doesn't take into account the native sequence setting, it's just to be called from DB.getNextID()
|
||||
*
|
||||
* @deprecated please use DB.getNextID (int, String, String)
|
||||
*/
|
||||
public static int getNextID (int AD_Client_ID, String TableName, String trxName)
|
||||
{
|
||||
if (TableName == null || TableName.length() == 0)
|
||||
throw new IllegalArgumentException("TableName missing");
|
||||
|
||||
int retValue = -1;
|
||||
|
||||
boolean isSystemNativeSequence = MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false);
|
||||
// Check AdempiereSys
|
||||
boolean adempiereSys = false;
|
||||
if (Ini.isClient())
|
||||
if (Ini.isClient())
|
||||
{
|
||||
adempiereSys = Ini.isPropertyBool(Ini.P_ADEMPIERESYS);
|
||||
}
|
||||
|
@ -101,13 +89,70 @@ public class MSequence extends X_AD_Sequence
|
|||
String sysProperty = Env.getCtx().getProperty("AdempiereSys", "N");
|
||||
adempiereSys = "y".equalsIgnoreCase(sysProperty) || "true".equalsIgnoreCase(sysProperty);
|
||||
}
|
||||
|
||||
if (adempiereSys && AD_Client_ID > 11)
|
||||
adempiereSys = false;
|
||||
//
|
||||
if (CLogMgt.isLevel(LOGLEVEL))
|
||||
s_log.log(LOGLEVEL, TableName + " - AdempiereSys=" + adempiereSys + " [" + trxName + "]");
|
||||
//begin vpj-cd e-evolution 09/02/2005 PostgreSQL
|
||||
if (CLogMgt.isLevel(Level.FINER))
|
||||
s_log.log(Level.FINER, TableName + " - AdempiereSys=" + adempiereSys + " [" + trxName + "]");
|
||||
|
||||
if (TableName == null || TableName.length() == 0)
|
||||
throw new IllegalArgumentException("TableName missing");
|
||||
|
||||
int retValue = -1;
|
||||
|
||||
// If maintaining official dictionary try to get the ID from http official server
|
||||
if (adempiereSys) {
|
||||
boolean isUseCentralizedID = MSysConfig.getBooleanValue(MSysConfig.DICTIONARY_ID_USE_CENTRALIZED_ID, true); // defaults to true
|
||||
if (isUseCentralizedID) {
|
||||
if (! isExceptionCentralized(TableName)) {
|
||||
// get ID from http site
|
||||
retValue = getNextOfficialID_HTTP(TableName);
|
||||
if (retValue > 0) {
|
||||
DB.executeUpdateEx("UPDATE AD_Sequence SET CurrentNextSys = ? + 1 WHERE Name=? AND IsTableID='Y' AND IsAutoSequence='Y'",
|
||||
new Object[] {retValue, TableName},
|
||||
trxName);
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
} else {
|
||||
// is an error to get a system ID from local
|
||||
throw new AdempiereException("System IDs must be always obtained from Centralized ID server");
|
||||
}
|
||||
}
|
||||
|
||||
boolean queryProjectServer = false;
|
||||
if (isTableWithEntityType(TableName))
|
||||
queryProjectServer = true;
|
||||
if (!queryProjectServer && MSequence.Table_Name.equalsIgnoreCase(TableName))
|
||||
queryProjectServer = true;
|
||||
|
||||
// If not official dictionary try to get the ID from http custom server - if configured
|
||||
if (queryProjectServer && ( ! adempiereSys ) && ( ! isExceptionCentralized(TableName) ) ) {
|
||||
boolean isUseProjectCentralizedID = MSysConfig.getBooleanValue(MSysConfig.PROJECT_ID_USE_CENTRALIZED_ID, false); // defaults to false
|
||||
if (isUseProjectCentralizedID) {
|
||||
// get ID from http site
|
||||
retValue = getNextProjectID_HTTP(TableName);
|
||||
if (retValue > 0) {
|
||||
DB.executeUpdateEx("UPDATE AD_Sequence SET CurrentNext = GREATEST(CurrentNext, ? + 1) WHERE Name=? AND IsTableID='Y' AND IsAutoSequence='Y'",
|
||||
new Object[] {retValue, TableName},
|
||||
trxName);
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSystemNativeSequence)
|
||||
{
|
||||
retValue = CConnection.get().getDatabase().getNextID(TableName+"_SQ", trxName);
|
||||
if (retValue == -1) {
|
||||
// try to create the sequence and try again
|
||||
MSequence.createTableSequence(Env.getCtx(), TableName, trxName, true);
|
||||
retValue = CConnection.get().getDatabase().getNextID(TableName+"_SQ", trxName);
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
// use AD_Sequence to obtain the next ID
|
||||
String selectSQL = null;
|
||||
if (DB.isOracle() == false)
|
||||
{
|
||||
|
@ -160,92 +205,30 @@ public class MSequence extends X_AD_Sequence
|
|||
+ ")");
|
||||
if (rs.next())
|
||||
{
|
||||
|
||||
// Get the table
|
||||
MTable table = MTable.get(Env.getCtx(), TableName);
|
||||
|
||||
int AD_Sequence_ID = rs.getInt(4);
|
||||
boolean gotFromHTTP = false;
|
||||
|
||||
// If maintaining official dictionary try to get the ID from http official server
|
||||
if (adempiereSys) {
|
||||
|
||||
String isUseCentralizedID = MSysConfig.getValue(MSysConfig.DICTIONARY_ID_USE_CENTRALIZED_ID, "Y"); // defaults to Y
|
||||
if ( ( ! isUseCentralizedID.equals("N") ) && ( ! isExceptionCentralized(TableName) ) ) {
|
||||
// get ID from http site
|
||||
retValue = getNextOfficialID_HTTP(TableName);
|
||||
if (retValue > 0) {
|
||||
PreparedStatement updateSQL = null;
|
||||
try {
|
||||
updateSQL = conn.prepareStatement("UPDATE AD_Sequence SET CurrentNextSys = ? + 1 WHERE AD_Sequence_ID = ?");
|
||||
updateSQL.setInt(1, retValue);
|
||||
updateSQL.setInt(2, AD_Sequence_ID);
|
||||
updateSQL.executeUpdate();
|
||||
} finally {
|
||||
DB.close(updateSQL);
|
||||
updateSQL = null;
|
||||
}
|
||||
}
|
||||
gotFromHTTP = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boolean queryProjectServer = false;
|
||||
if (table.getColumn("EntityType") != null)
|
||||
queryProjectServer = true;
|
||||
if (!queryProjectServer && MSequence.Table_Name.equalsIgnoreCase(TableName))
|
||||
queryProjectServer = true;
|
||||
|
||||
// If not official dictionary try to get the ID from http custom server - if configured
|
||||
if (queryProjectServer && ( ! adempiereSys ) && ( ! isExceptionCentralized(TableName) ) ) {
|
||||
|
||||
String isUseProjectCentralizedID = MSysConfig.getValue(MSysConfig.PROJECT_ID_USE_CENTRALIZED_ID, "N"); // defaults to N
|
||||
if (isUseProjectCentralizedID.equals("Y")) {
|
||||
// get ID from http site
|
||||
retValue = getNextProjectID_HTTP(TableName);
|
||||
if (retValue > 0) {
|
||||
PreparedStatement updateSQL = null;
|
||||
try {
|
||||
updateSQL = conn.prepareStatement("UPDATE AD_Sequence SET CurrentNext = GREATEST(CurrentNext, ? + 1) WHERE AD_Sequence_ID = ?");
|
||||
updateSQL.setInt(1, retValue);
|
||||
updateSQL.setInt(2, AD_Sequence_ID);
|
||||
updateSQL.executeUpdate();
|
||||
} finally {
|
||||
DB.close(updateSQL);
|
||||
updateSQL = null;
|
||||
}
|
||||
}
|
||||
gotFromHTTP = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! gotFromHTTP) {
|
||||
PreparedStatement updateSQL = null;
|
||||
try
|
||||
{
|
||||
int incrementNo = rs.getInt(3);
|
||||
if (adempiereSys) {
|
||||
String updateCmd = "UPDATE AD_Sequence SET CurrentNextSys=CurrentNextSys+? WHERE AD_Sequence_ID=?";
|
||||
if (!DB.isOracle() && !DB.isPostgreSQL())
|
||||
updateCmd = DB.getDatabase().convertStatement(updateCmd);
|
||||
updateSQL = conn.prepareStatement(updateCmd);
|
||||
retValue = rs.getInt(2);
|
||||
} else {
|
||||
String updateCmd = "UPDATE AD_Sequence SET CurrentNext=CurrentNext+? WHERE AD_Sequence_ID=?";
|
||||
if (!DB.isOracle() && !DB.isPostgreSQL())
|
||||
updateCmd = DB.getDatabase().convertStatement(updateCmd);
|
||||
updateSQL = conn.prepareStatement(updateCmd);
|
||||
retValue = rs.getInt(1);
|
||||
}
|
||||
updateSQL.setInt(1, incrementNo);
|
||||
updateSQL.setInt(2, AD_Sequence_ID);
|
||||
updateSQL.executeUpdate();
|
||||
} finally {
|
||||
DB.close(updateSQL);
|
||||
updateSQL = null;
|
||||
PreparedStatement updateSQL = null;
|
||||
try
|
||||
{
|
||||
int incrementNo = rs.getInt(3);
|
||||
if (adempiereSys) {
|
||||
String updateCmd = "UPDATE AD_Sequence SET CurrentNextSys=CurrentNextSys+? WHERE AD_Sequence_ID=?";
|
||||
if (!DB.isOracle() && !DB.isPostgreSQL())
|
||||
updateCmd = DB.getDatabase().convertStatement(updateCmd);
|
||||
updateSQL = conn.prepareStatement(updateCmd);
|
||||
retValue = rs.getInt(2);
|
||||
} else {
|
||||
String updateCmd = "UPDATE AD_Sequence SET CurrentNext=CurrentNext+? WHERE AD_Sequence_ID=?";
|
||||
if (!DB.isOracle() && !DB.isPostgreSQL())
|
||||
updateCmd = DB.getDatabase().convertStatement(updateCmd);
|
||||
updateSQL = conn.prepareStatement(updateCmd);
|
||||
retValue = rs.getInt(1);
|
||||
}
|
||||
updateSQL.setInt(1, incrementNo);
|
||||
updateSQL.setInt(2, AD_Sequence_ID);
|
||||
updateSQL.executeUpdate();
|
||||
} finally {
|
||||
DB.close(updateSQL);
|
||||
updateSQL = null;
|
||||
}
|
||||
|
||||
//if (trx == null)
|
||||
|
@ -636,8 +619,8 @@ public class MSequence extends X_AD_Sequence
|
|||
int seqID = ( definite ? dt.getDefiniteSequence_ID() : dt.getDocNoSequence_ID() );
|
||||
MSequence seq = new MSequence(Env.getCtx(), seqID, trxName);
|
||||
|
||||
if (CLogMgt.isLevel(LOGLEVEL))
|
||||
s_log.log(LOGLEVEL, "DocType_ID=" + C_DocType_ID + " [" + trxName + "]");
|
||||
if (CLogMgt.isLevel(Level.FINER))
|
||||
s_log.log(Level.FINER, "DocType_ID=" + C_DocType_ID + " [" + trxName + "]");
|
||||
|
||||
return getDocumentNoFromSeq(seq, trxName, po);
|
||||
} // getDocumentNo
|
||||
|
@ -1387,6 +1370,19 @@ public class MSequence extends X_AD_Sequence
|
|||
return false;
|
||||
}
|
||||
|
||||
private static CCache<String,String> tablesWithEntityType = new CCache<String,String>(Table_Name, "TablesWithEntityType", 60, 0, false, 0);
|
||||
|
||||
private synchronized static boolean isTableWithEntityType(String tableName) {
|
||||
if (tablesWithEntityType == null || tablesWithEntityType.size() == 0) {
|
||||
final String sql = "SELECT TableName FROM AD_Table WHERE AD_Table_ID IN (SELECT AD_Table_ID FROM AD_Column WHERE ColumnName='EntityType') ORDER BY TableName";
|
||||
List<List<Object>> list = DB.getSQLArrayObjectsEx(null, sql);
|
||||
for (List<Object> row : list) {
|
||||
tablesWithEntityType.put((String)row.get(0), "");
|
||||
}
|
||||
}
|
||||
return (tablesWithEntityType.get(tableName) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean beforeSave(boolean newRecord) {
|
||||
if (isStartNewMonth() && !isStartNewYear())
|
||||
|
|
|
@ -1823,33 +1823,8 @@ public final class DB
|
|||
* @param trxName optional Transaction Name
|
||||
* @return next no
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static int getNextID (int AD_Client_ID, String TableName, String trxName)
|
||||
{
|
||||
boolean SYSTEM_NATIVE_SEQUENCE = MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false);
|
||||
// Check AdempiereSys
|
||||
boolean adempiereSys = false;
|
||||
if (Ini.isClient())
|
||||
{
|
||||
adempiereSys = Ini.isPropertyBool(Ini.P_ADEMPIERESYS);
|
||||
}
|
||||
else
|
||||
{
|
||||
String sysProperty = Env.getCtx().getProperty("AdempiereSys", "N");
|
||||
adempiereSys = "y".equalsIgnoreCase(sysProperty) || "true".equalsIgnoreCase(sysProperty);
|
||||
}
|
||||
|
||||
if(SYSTEM_NATIVE_SEQUENCE && !adempiereSys)
|
||||
{
|
||||
int m_sequence_id = CConnection.get().getDatabase().getNextID(TableName+"_SQ", trxName);
|
||||
if (m_sequence_id == -1) {
|
||||
// try to create the sequence and try again
|
||||
MSequence.createTableSequence(Env.getCtx(), TableName, trxName, true);
|
||||
m_sequence_id = CConnection.get().getDatabase().getNextID(TableName+"_SQ", trxName);
|
||||
}
|
||||
return m_sequence_id;
|
||||
}
|
||||
|
||||
return MSequence.getNextID (AD_Client_ID, TableName, trxName); // it is ok to call deprecated method here
|
||||
} // getNextID
|
||||
|
||||
|
|
Loading…
Reference in New Issue