IDEMPIERE-4911 Silent fail when translated column is shorter than original column (FHCA-2888) (#844)
* IDEMPIERE-4911 Silent fail when translated column is shorter than original column (FHCA-2888) Changes: * Saving a value that doesn't fit in the translation now fails with a proper user understandable message * Synchronize Doc Translation now fails with a user understandable message in case it fails because a value doesn't fit * When updating a column on a translation table, check for the size of the original column and update the size accordingly * When updating a translated column, show warnings to user about creating the table, or creating the column, or updating the column size * IDEMPIERE-4911 Silent fail when translated column is shorter than original column (FHCA-2888) Improve message for end user
This commit is contained in:
parent
f912cf2c21
commit
0167c91424
|
@ -0,0 +1,27 @@
|
||||||
|
SET SQLBLANKLINES ON
|
||||||
|
SET DEFINE OFF
|
||||||
|
|
||||||
|
-- IDEMPIERE-4911 Silent fail when translated column is shorter than original column (FHCA-2888)
|
||||||
|
-- Aug 18, 2021, 8:01:59 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','...',0,0,'Y',TO_DATE('2021-08-18 20:01:59','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-08-18 20:01:59','YYYY-MM-DD HH24:MI:SS'),100,200714,'MismatchTrlColumnSize','D','14ca00be-1dc1-4e27-b908-257704aae45d')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2021, 8:13:56 PM CEST
|
||||||
|
UPDATE AD_Message SET MsgText='Error synchronizing translation, string too long', MsgTip='There is a mismatch in the size of a translated column. Please contact the system administrator to correct the problem.',Updated=TO_DATE('2021-08-18 20:13:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200714
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2021, 9:24:16 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Do not forget to create the corresponding translation table {0} with column {1}',0,0,'Y',TO_DATE('2021-08-18 21:24:15','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-08-18 21:24:15','YYYY-MM-DD HH24:MI:SS'),100,200715,'WarnCreateTrlTable','D','df97a71a-bb65-4ed5-b7dc-000610f807f5')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2021, 9:24:27 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Do not forget to create the translation column {0}.{1}',0,0,'Y',TO_DATE('2021-08-18 21:24:26','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-08-18 21:24:26','YYYY-MM-DD HH24:MI:SS'),100,200716,'WarnCreateTrlColumn','D','7bd54fc7-40cc-408d-b88e-ec25f9ae28fa')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2021, 9:24:38 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Do not forget to increase the size on translation column {0}.{1} to {2}',0,0,'Y',TO_DATE('2021-08-18 21:24:38','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-08-18 21:24:38','YYYY-MM-DD HH24:MI:SS'),100,200717,'WarnUpdateSizeTrlTable','D','d5951ecd-3d4f-4438-bc48-8d3fbace8693')
|
||||||
|
;
|
||||||
|
|
||||||
|
SELECT register_migration_script('202108182002_IDEMPIERE-4911.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
-- IDEMPIERE-4911 Silent fail when translated column is shorter than original column (FHCA-2888)
|
||||||
|
-- Aug 18, 2021, 8:01:59 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','...',0,0,'Y',TO_TIMESTAMP('2021-08-18 20:01:59','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-08-18 20:01:59','YYYY-MM-DD HH24:MI:SS'),100,200714,'MismatchTrlColumnSize','D','14ca00be-1dc1-4e27-b908-257704aae45d')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2021, 8:13:56 PM CEST
|
||||||
|
UPDATE AD_Message SET MsgText='Error synchronizing translation, string too long', MsgTip='There is a mismatch in the size of a translated column. Please contact the system administrator to correct the problem.',Updated=TO_TIMESTAMP('2021-08-18 20:13:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200714
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2021, 9:24:16 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Do not forget to create the corresponding translation table {0} with column {1}',0,0,'Y',TO_TIMESTAMP('2021-08-18 21:24:15','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-08-18 21:24:15','YYYY-MM-DD HH24:MI:SS'),100,200715,'WarnCreateTrlTable','D','df97a71a-bb65-4ed5-b7dc-000610f807f5')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2021, 9:24:27 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Do not forget to create the translation column {0}.{1}',0,0,'Y',TO_TIMESTAMP('2021-08-18 21:24:26','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-08-18 21:24:26','YYYY-MM-DD HH24:MI:SS'),100,200716,'WarnCreateTrlColumn','D','7bd54fc7-40cc-408d-b88e-ec25f9ae28fa')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2021, 9:24:38 PM CEST
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Do not forget to increase the size on translation column {0}.{1} to {2}',0,0,'Y',TO_TIMESTAMP('2021-08-18 21:24:38','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-08-18 21:24:38','YYYY-MM-DD HH24:MI:SS'),100,200717,'WarnUpdateSizeTrlTable','D','d5951ecd-3d4f-4438-bc48-8d3fbace8693')
|
||||||
|
;
|
||||||
|
|
||||||
|
SELECT register_migration_script('202108182002_IDEMPIERE-4911.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
|
import org.adempiere.exceptions.DBException;
|
||||||
import org.compiere.model.MClient;
|
import org.compiere.model.MClient;
|
||||||
import org.compiere.model.MColumn;
|
import org.compiere.model.MColumn;
|
||||||
import org.compiere.model.MTable;
|
import org.compiere.model.MTable;
|
||||||
|
@ -29,6 +31,7 @@ import org.compiere.util.AdempiereUserError;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.DisplayType;
|
import org.compiere.util.DisplayType;
|
||||||
import org.compiere.util.Language;
|
import org.compiere.util.Language;
|
||||||
|
import org.compiere.util.Msg;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,7 +106,8 @@ public class TranslationDocSync extends SvrProcess
|
||||||
String baseTable = trlTable.substring(0, trlTable.length()-4);
|
String baseTable = trlTable.substring(0, trlTable.length()-4);
|
||||||
|
|
||||||
if (log.isLoggable(Level.CONFIG)) log.config(baseTable + ": " + columnNames);
|
if (log.isLoggable(Level.CONFIG)) log.config(baseTable + ": " + columnNames);
|
||||||
|
|
||||||
|
try {
|
||||||
if (client.isMultiLingualDocument()) {
|
if (client.isMultiLingualDocument()) {
|
||||||
String baselang = Language.getBaseAD_Language();
|
String baselang = Language.getBaseAD_Language();
|
||||||
if (client.getAD_Language().equals(baselang)) {
|
if (client.getAD_Language().equals(baselang)) {
|
||||||
|
@ -118,8 +122,8 @@ public class TranslationDocSync extends SvrProcess
|
||||||
.append(baseTable).append("_ID=b.").append(baseTable).append("_ID) WHERE AD_Client_ID=")
|
.append(baseTable).append("_ID=b.").append(baseTable).append("_ID) WHERE AD_Client_ID=")
|
||||||
.append(getAD_Client_ID()).append(" AND AD_Language=").append(DB.TO_STRING(client.getAD_Language()));
|
.append(getAD_Client_ID()).append(" AND AD_Language=").append(DB.TO_STRING(client.getAD_Language()));
|
||||||
|
|
||||||
int no = DB.executeUpdate(sql.toString(), get_TrxName());
|
int no = DB.executeUpdateEx(sql.toString(), get_TrxName());
|
||||||
addLog(0, null, new BigDecimal(no), baseTable);
|
addBufferLog(0, null, new BigDecimal(no), baseTable, 0, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// auto update all translations
|
// auto update all translations
|
||||||
|
@ -129,9 +133,18 @@ public class TranslationDocSync extends SvrProcess
|
||||||
.append(baseTable).append("_ID=b.").append(baseTable).append("_ID) WHERE AD_Client_ID=")
|
.append(baseTable).append("_ID=b.").append(baseTable).append("_ID) WHERE AD_Client_ID=")
|
||||||
.append(getAD_Client_ID());
|
.append(getAD_Client_ID());
|
||||||
|
|
||||||
int no = DB.executeUpdate(sql.toString(), get_TrxName());
|
int no = DB.executeUpdateEx(sql.toString(), get_TrxName());
|
||||||
addLog(0, null, new BigDecimal(no), baseTable);
|
addBufferLog(0, null, new BigDecimal(no), baseTable, 0, 0);
|
||||||
}
|
}
|
||||||
|
} catch (DBException e) {
|
||||||
|
String msg = trlTable + " -> ";
|
||||||
|
if (DBException.isValueTooLarge(e)) {
|
||||||
|
msg += Msg.getMsg(getCtx(), "MismatchTrlColumnSize");
|
||||||
|
} else {
|
||||||
|
msg += e.getLocalizedMessage();
|
||||||
|
}
|
||||||
|
throw new AdempiereException(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
} // processTable
|
} // processTable
|
||||||
|
|
||||||
|
|
|
@ -36,13 +36,14 @@ import org.compiere.util.DB;
|
||||||
*/
|
*/
|
||||||
public class DBException extends AdempiereException
|
public class DBException extends AdempiereException
|
||||||
{
|
{
|
||||||
public static final String DATABASE_OPERATION_TIMEOUT_MSG = "DatabaseOperationTimeout";
|
|
||||||
public static final String DELETE_ERROR_DEPENDENT_MSG = "DeleteErrorDependent";
|
|
||||||
public static final String SAVE_ERROR_NOT_UNIQUE_MSG = "SaveErrorNotUnique";
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 4264201718343118625L;
|
private static final long serialVersionUID = -1961265420169932726L;
|
||||||
|
|
||||||
|
public static final String DATABASE_OPERATION_TIMEOUT_MSG = "DatabaseOperationTimeout";
|
||||||
|
public static final String DELETE_ERROR_DEPENDENT_MSG = "DeleteErrorDependent";
|
||||||
|
public static final String SAVE_ERROR_NOT_UNIQUE_MSG = "SaveErrorNotUnique";
|
||||||
private String m_sql = null;
|
private String m_sql = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,7 +213,18 @@ public class DBException extends AdempiereException
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if value too large for column exception (aka ORA-12899)
|
||||||
|
* @param e exception
|
||||||
|
*/
|
||||||
|
public static boolean isValueTooLarge(Exception e) {
|
||||||
|
if (DB.isPostgreSQL())
|
||||||
|
return isSQLState(e, "22001");
|
||||||
|
//
|
||||||
|
return isErrorCode(e, 12899);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param e
|
* @param e
|
||||||
*/
|
*/
|
||||||
|
@ -227,4 +239,5 @@ public class DBException extends AdempiereException
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // DBException
|
} // DBException
|
||||||
|
|
|
@ -524,6 +524,21 @@ public class MColumn extends X_AD_Column implements ImmutablePOSupport
|
||||||
LogicEvaluator.validate(getReadOnlyLogic());
|
LogicEvaluator.validate(getReadOnlyLogic());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IDEMPIERE-4911
|
||||||
|
MTable table = MTable.get(getAD_Table_ID());
|
||||||
|
String tableName = table.getTableName();
|
||||||
|
if (tableName.toLowerCase().endsWith("_trl")) {
|
||||||
|
String parentTable = tableName.substring(0, tableName.length()-4);
|
||||||
|
MColumn column = MColumn.get(getCtx(), parentTable, colname);
|
||||||
|
if (column != null && column.isTranslated()) {
|
||||||
|
if (getFieldLength() < column.getFieldLength()) {
|
||||||
|
log.saveWarning("Warning", "Size increased to " + column.getFieldLength() + " in translated column " + tableName + "." + colname);
|
||||||
|
setFieldLength(column.getFieldLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
|
@ -543,7 +558,26 @@ public class MColumn extends X_AD_Column implements ImmutablePOSupport
|
||||||
|| "EntityType".equals(get_ValueOld(COLUMNNAME_ColumnName).toString()))) {
|
|| "EntityType".equals(get_ValueOld(COLUMNNAME_ColumnName).toString()))) {
|
||||||
MChangeLog.resetLoggedList();
|
MChangeLog.resetLoggedList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IDEMPIERE-4911
|
||||||
|
if (isTranslated()) {
|
||||||
|
MTable table = MTable.get(getAD_Table_ID());
|
||||||
|
String trlTableName = table.getTableName() + "_Trl";
|
||||||
|
MTable trlTable = MTable.get(getCtx(), trlTableName);
|
||||||
|
if (trlTable == null) {
|
||||||
|
log.saveWarning("Warning", Msg.getMsg(getCtx(), "WarnCreateTrlTable", new Object[] {trlTableName, getColumnName()}));
|
||||||
|
} else {
|
||||||
|
MColumn trlColumn = MColumn.get(getCtx(), trlTableName, getColumnName());
|
||||||
|
if (trlColumn == null) {
|
||||||
|
log.saveWarning("Warning", Msg.getMsg(getCtx(), "WarnCreateTrlColumn", new Object[] {trlTableName, getColumnName()}));
|
||||||
|
} else {
|
||||||
|
if (trlColumn.getFieldLength() < getFieldLength()) {
|
||||||
|
log.saveWarning("Warning", Msg.getMsg(getCtx(), "WarnUpdateSizeTrlTable", new Object[] {trlTableName, getColumnName(), getFieldLength()}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
} // afterSave
|
} // afterSave
|
||||||
|
|
||||||
|
|
|
@ -3806,7 +3806,18 @@ public abstract class PO
|
||||||
.append(" AND NOT EXISTS (SELECT * FROM ").append(tableName)
|
.append(" AND NOT EXISTS (SELECT * FROM ").append(tableName)
|
||||||
.append("_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.")
|
.append("_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.")
|
||||||
.append(keyColumn).append("=t.").append(keyColumn).append(")");
|
.append(keyColumn).append("=t.").append(keyColumn).append(")");
|
||||||
int no = DB.executeUpdate(sql.toString(), m_trxName);
|
int no = -1;
|
||||||
|
try {
|
||||||
|
no = DB.executeUpdateEx(sql.toString(), m_trxName);
|
||||||
|
} catch (DBException e) {
|
||||||
|
String msg;
|
||||||
|
if (DBException.isValueTooLarge(e)) {
|
||||||
|
msg = Msg.getMsg(getCtx(), "MismatchTrlColumnSize");
|
||||||
|
} else {
|
||||||
|
msg = "insertTranslations -> " + e.getLocalizedMessage();
|
||||||
|
}
|
||||||
|
throw new AdempiereException(msg, e);
|
||||||
|
}
|
||||||
if (uuidColumn != null && !uuidFunction) {
|
if (uuidColumn != null && !uuidFunction) {
|
||||||
UUIDGenerator.updateUUID(uuidColumn, get_TrxName());
|
UUIDGenerator.updateUUID(uuidColumn, get_TrxName());
|
||||||
}
|
}
|
||||||
|
@ -3887,6 +3898,7 @@ public abstract class PO
|
||||||
StringBuilder andNotBaseLang = new StringBuilder(" AND AD_Language!=").append(DB.TO_STRING(baselang));
|
StringBuilder andNotBaseLang = new StringBuilder(" AND AD_Language!=").append(DB.TO_STRING(baselang));
|
||||||
int no = -1;
|
int no = -1;
|
||||||
|
|
||||||
|
try {
|
||||||
if (client.isMultiLingualDocument()) {
|
if (client.isMultiLingualDocument()) {
|
||||||
if (client.getAD_Language().equals(baselang)) {
|
if (client.getAD_Language().equals(baselang)) {
|
||||||
// tenant language = base language
|
// tenant language = base language
|
||||||
|
@ -3895,7 +3907,7 @@ public abstract class PO
|
||||||
.append(sqlupdate)
|
.append(sqlupdate)
|
||||||
.append("IsTranslated='N'")
|
.append("IsTranslated='N'")
|
||||||
.append(whereid);
|
.append(whereid);
|
||||||
no = DB.executeUpdate(sqlexec.toString(), m_trxName);
|
no = DB.executeUpdateEx(sqlexec.toString(), m_trxName);
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
||||||
} else {
|
} else {
|
||||||
// tenant language <> base language
|
// tenant language <> base language
|
||||||
|
@ -3907,7 +3919,7 @@ public abstract class PO
|
||||||
.append("IsTranslated='Y'")
|
.append("IsTranslated='Y'")
|
||||||
.append(whereid)
|
.append(whereid)
|
||||||
.append(getAD_Client_ID() == 0 ? andBaseLang : andClientLang);
|
.append(getAD_Client_ID() == 0 ? andBaseLang : andClientLang);
|
||||||
no = DB.executeUpdate(sqlexec.toString(), m_trxName);
|
no = DB.executeUpdateEx(sqlexec.toString(), m_trxName);
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
||||||
if (no >= 0) {
|
if (no >= 0) {
|
||||||
// set other translations as untranslated
|
// set other translations as untranslated
|
||||||
|
@ -3916,7 +3928,7 @@ public abstract class PO
|
||||||
.append("IsTranslated='N'")
|
.append("IsTranslated='N'")
|
||||||
.append(whereid)
|
.append(whereid)
|
||||||
.append(getAD_Client_ID() == 0 ? andNotBaseLang : andNotClientLang);
|
.append(getAD_Client_ID() == 0 ? andNotBaseLang : andNotClientLang);
|
||||||
no = DB.executeUpdate(sqlexec.toString(), m_trxName);
|
no = DB.executeUpdateEx(sqlexec.toString(), m_trxName);
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3928,9 +3940,19 @@ public abstract class PO
|
||||||
.append(sqlcols)
|
.append(sqlcols)
|
||||||
.append("IsTranslated='Y'")
|
.append("IsTranslated='Y'")
|
||||||
.append(whereid);
|
.append(whereid);
|
||||||
no = DB.executeUpdate(sqlexec.toString(), m_trxName);
|
no = DB.executeUpdateEx(sqlexec.toString(), m_trxName);
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
||||||
}
|
}
|
||||||
|
} catch (DBException e) {
|
||||||
|
String msg;
|
||||||
|
if (DBException.isValueTooLarge(e)) {
|
||||||
|
msg = Msg.getMsg(getCtx(), "MismatchTrlColumnSize");
|
||||||
|
} else {
|
||||||
|
msg = "updateTranslations -> " + e.getLocalizedMessage();
|
||||||
|
}
|
||||||
|
throw new AdempiereException(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
return no >= 0;
|
return no >= 0;
|
||||||
} // updateTranslations
|
} // updateTranslations
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue