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.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.exceptions.DBException;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MColumn;
|
||||
import org.compiere.model.MTable;
|
||||
|
@ -29,6 +31,7 @@ import org.compiere.util.AdempiereUserError;
|
|||
import org.compiere.util.DB;
|
||||
import org.compiere.util.DisplayType;
|
||||
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);
|
||||
|
||||
if (log.isLoggable(Level.CONFIG)) log.config(baseTable + ": " + columnNames);
|
||||
|
||||
|
||||
try {
|
||||
if (client.isMultiLingualDocument()) {
|
||||
String baselang = Language.getBaseAD_Language();
|
||||
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(getAD_Client_ID()).append(" AND AD_Language=").append(DB.TO_STRING(client.getAD_Language()));
|
||||
|
||||
int no = DB.executeUpdate(sql.toString(), get_TrxName());
|
||||
addLog(0, null, new BigDecimal(no), baseTable);
|
||||
int no = DB.executeUpdateEx(sql.toString(), get_TrxName());
|
||||
addBufferLog(0, null, new BigDecimal(no), baseTable, 0, 0);
|
||||
}
|
||||
} else {
|
||||
// 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(getAD_Client_ID());
|
||||
|
||||
int no = DB.executeUpdate(sql.toString(), get_TrxName());
|
||||
addLog(0, null, new BigDecimal(no), baseTable);
|
||||
int no = DB.executeUpdateEx(sql.toString(), get_TrxName());
|
||||
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
|
||||
|
||||
|
|
|
@ -36,13 +36,14 @@ import org.compiere.util.DB;
|
|||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -212,7 +213,18 @@ public class DBException extends AdempiereException
|
|||
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
|
||||
*/
|
||||
|
@ -227,4 +239,5 @@ public class DBException extends AdempiereException
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
} // DBException
|
||||
|
|
|
@ -524,6 +524,21 @@ public class MColumn extends X_AD_Column implements ImmutablePOSupport
|
|||
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;
|
||||
} // beforeSave
|
||||
|
||||
|
@ -543,7 +558,26 @@ public class MColumn extends X_AD_Column implements ImmutablePOSupport
|
|||
|| "EntityType".equals(get_ValueOld(COLUMNNAME_ColumnName).toString()))) {
|
||||
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;
|
||||
} // afterSave
|
||||
|
||||
|
|
|
@ -3806,7 +3806,18 @@ public abstract class PO
|
|||
.append(" AND NOT EXISTS (SELECT * FROM ").append(tableName)
|
||||
.append("_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.")
|
||||
.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) {
|
||||
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));
|
||||
int no = -1;
|
||||
|
||||
try {
|
||||
if (client.isMultiLingualDocument()) {
|
||||
if (client.getAD_Language().equals(baselang)) {
|
||||
// tenant language = base language
|
||||
|
@ -3895,7 +3907,7 @@ public abstract class PO
|
|||
.append(sqlupdate)
|
||||
.append("IsTranslated='N'")
|
||||
.append(whereid);
|
||||
no = DB.executeUpdate(sqlexec.toString(), m_trxName);
|
||||
no = DB.executeUpdateEx(sqlexec.toString(), m_trxName);
|
||||
if (log.isLoggable(Level.FINE)) log.fine("#" + no);
|
||||
} else {
|
||||
// tenant language <> base language
|
||||
|
@ -3907,7 +3919,7 @@ public abstract class PO
|
|||
.append("IsTranslated='Y'")
|
||||
.append(whereid)
|
||||
.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 (no >= 0) {
|
||||
// set other translations as untranslated
|
||||
|
@ -3916,7 +3928,7 @@ public abstract class PO
|
|||
.append("IsTranslated='N'")
|
||||
.append(whereid)
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
@ -3928,9 +3940,19 @@ public abstract class PO
|
|||
.append(sqlcols)
|
||||
.append("IsTranslated='Y'")
|
||||
.append(whereid);
|
||||
no = DB.executeUpdate(sqlexec.toString(), m_trxName);
|
||||
no = DB.executeUpdateEx(sqlexec.toString(), m_trxName);
|
||||
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;
|
||||
} // updateTranslations
|
||||
|
||||
|
|
Loading…
Reference in New Issue