From d70244f8bc0335142e97c96e5aaa5a3285452614 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Mon, 29 Jul 2013 17:14:52 +0800 Subject: [PATCH] IDEMPIERE-1207 Fixed inconsistent error message for well known database exception. --- .../oracle/201307290906_IDEMPIERE-1207.sql | 13 + .../201307290906_IDEMPIERE-1207.sql | 13 + .../org/adempiere/exceptions/DBException.java | 18 + .../src/org/compiere/model/GridTable.java | 16 +- .../src/org/compiere/model/MColumn.java | 3 +- .../src/org/compiere/model/MUser.java | 3 +- .../src/org/compiere/model/M_Element.java | 3 +- .../src/org/compiere/model/PO.java | 375 +++++++++++------- .../src/org/compiere/util/DB.java | 3 +- .../src/org/compiere/util/Trx.java | 6 + 10 files changed, 306 insertions(+), 147 deletions(-) create mode 100644 migration/i1.0c-release/oracle/201307290906_IDEMPIERE-1207.sql create mode 100644 migration/i1.0c-release/postgresql/201307290906_IDEMPIERE-1207.sql diff --git a/migration/i1.0c-release/oracle/201307290906_IDEMPIERE-1207.sql b/migration/i1.0c-release/oracle/201307290906_IDEMPIERE-1207.sql new file mode 100644 index 0000000000..8e220aac05 --- /dev/null +++ b/migration/i1.0c-release/oracle/201307290906_IDEMPIERE-1207.sql @@ -0,0 +1,13 @@ +-- Jul 29, 2013 5:05:15 PM MYT +-- IDEMPIERE-1207 Fixed inconsistent error message for well known database exception +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('E','The database operation timed out. Please try again later.',200217,'D','bfc4529a-0ec2-4e8b-92d4-f86ca829cd4d','DatabaseOperationTimeout','Y',TO_DATE('2013-07-29 17:05:02','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_DATE('2013-07-29 17:05:02','YYYY-MM-DD HH24:MI:SS'),0) +; + +-- Jul 29, 2013 5:05:15 PM MYT +-- IDEMPIERE-1207 Fixed inconsistent error message for well known database exception +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200217 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +SELECT register_migration_script('201307290906_IDEMPIERE-1207.sql') FROM dual +; + diff --git a/migration/i1.0c-release/postgresql/201307290906_IDEMPIERE-1207.sql b/migration/i1.0c-release/postgresql/201307290906_IDEMPIERE-1207.sql new file mode 100644 index 0000000000..5db8b1bfbd --- /dev/null +++ b/migration/i1.0c-release/postgresql/201307290906_IDEMPIERE-1207.sql @@ -0,0 +1,13 @@ +-- Jul 29, 2013 5:05:15 PM MYT +-- IDEMPIERE-1207 Fixed inconsistent error message for well known database exception +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('E','The database operation timed out. Please try again later.',200217,'D','bfc4529a-0ec2-4e8b-92d4-f86ca829cd4d','DatabaseOperationTimeout','Y',TO_TIMESTAMP('2013-07-29 17:05:02','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_TIMESTAMP('2013-07-29 17:05:02','YYYY-MM-DD HH24:MI:SS'),0) +; + +-- Jul 29, 2013 5:05:15 PM MYT +-- IDEMPIERE-1207 Fixed inconsistent error message for well known database exception +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200217 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +SELECT register_migration_script('201307290906_IDEMPIERE-1207.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/adempiere/exceptions/DBException.java b/org.adempiere.base/src/org/adempiere/exceptions/DBException.java index 48e325b36e..5f35f5c34b 100644 --- a/org.adempiere.base/src/org/adempiere/exceptions/DBException.java +++ b/org.adempiere.base/src/org/adempiere/exceptions/DBException.java @@ -36,6 +36,9 @@ 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"; /** * */ @@ -198,4 +201,19 @@ public class DBException extends AdempiereException return isSQLState(e, "57014"); return isErrorCode(e, 1013); } + + /** + * @param e + */ + public static String getDefaultDBExceptionMessage(Exception e) { + if (isUniqueContraintError(e)) { + return SAVE_ERROR_NOT_UNIQUE_MSG; + } else if (isChildRecordFoundError(e)) { + return DELETE_ERROR_DEPENDENT_MSG; + } else if (isTimeout(e)) { + return DATABASE_OPERATION_TIMEOUT_MSG; + } else { + return null; + } + } } // DBException diff --git a/org.adempiere.base/src/org/compiere/model/GridTable.java b/org.adempiere.base/src/org/compiere/model/GridTable.java index 94632933a3..bec1206e6f 100644 --- a/org.adempiere.base/src/org/compiere/model/GridTable.java +++ b/org.adempiere.base/src/org/compiere/model/GridTable.java @@ -60,6 +60,7 @@ import org.compiere.util.MSort; import org.compiere.util.Msg; import org.compiere.util.SecureEngine; import org.compiere.util.Trx; +import org.compiere.util.Util; import org.compiere.util.ValueNamePair; /** @@ -2029,10 +2030,11 @@ public class GridTable extends AbstractTableModel { String msg = "SaveError"; - if (DBException.isUniqueContraintError(e)) // Unique Constraint + String dbException = DBException.getDefaultDBExceptionMessage(e); + if (!Util.isEmpty(dbException)) { - log.log(Level.SEVERE, "Key Not Unique", e); - msg = "SaveErrorNotUnique"; + log.log(Level.SEVERE, dbException, e); + msg = dbException; } else log.log(Level.SEVERE, select.toString(), e); @@ -2175,9 +2177,6 @@ public class GridTable extends AbstractTableModel info = ppE.getName(); if ("DBExecuteError".equals(msg)) info = "DBExecuteError:" + info; - // Unique Constraint - if (DBException.isUniqueContraintError(CLogger.retrieveException())) - msg = "SaveErrorNotUnique"; } fireDataStatusEEvent(msg, info, true); return SAVE_ERROR; @@ -2668,8 +2667,9 @@ public class GridTable extends AbstractTableModel { log.log(Level.SEVERE, sql.toString(), e); String msg = "DeleteError"; - if (DBException.isChildRecordFoundError(e)) - msg = "DeleteErrorDependent"; + String dbMsg = DBException.getDefaultDBExceptionMessage(e); + if (!Util.isEmpty(dbMsg)) + msg = dbMsg; fireDataStatusEEvent(msg, e.getLocalizedMessage(), true); return false; } diff --git a/org.adempiere.base/src/org/compiere/model/MColumn.java b/org.adempiere.base/src/org/compiere/model/MColumn.java index a9cb759b1a..a4a98ca0f8 100644 --- a/org.adempiere.base/src/org/compiere/model/MColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MColumn.java @@ -28,6 +28,7 @@ import java.util.Locale; import java.util.Properties; import java.util.logging.Level; +import org.adempiere.exceptions.DBException; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -276,7 +277,7 @@ public class MColumn extends X_AD_Column new Object[] {getAD_Table_ID(), getAD_Column_ID(), getSeqNo()}); if (cnt>0) { - log.saveError("SaveErrorNotUnique", Msg.getElement(getCtx(), COLUMNNAME_SeqNo)); + log.saveError(DBException.SAVE_ERROR_NOT_UNIQUE_MSG, Msg.getElement(getCtx(), COLUMNNAME_SeqNo)); return false; } } diff --git a/org.adempiere.base/src/org/compiere/model/MUser.java b/org.adempiere.base/src/org/compiere/model/MUser.java index 6c0a3cb196..e91b7f9e44 100644 --- a/org.adempiere.base/src/org/compiere/model/MUser.java +++ b/org.adempiere.base/src/org/compiere/model/MUser.java @@ -33,6 +33,7 @@ import java.util.logging.Level; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; +import org.adempiere.exceptions.DBException; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -910,7 +911,7 @@ public class MUser extends X_AD_User "SELECT COUNT(*) FROM AD_User WHERE Password IS NOT NULL AND EMail=? AND AD_Client_ID=? AND AD_User_ID!=?", getEMail(), getAD_Client_ID(), getAD_User_ID()); if (cnt > 0) { - log.saveError("SaveError", Msg.getMsg(getCtx(), "SaveErrorNotUnique", true) + Msg.getElement(getCtx(), COLUMNNAME_EMail)); + log.saveError("SaveError", Msg.getMsg(getCtx(), DBException.SAVE_ERROR_NOT_UNIQUE_MSG, true) + Msg.getElement(getCtx(), COLUMNNAME_EMail)); return false; } } diff --git a/org.adempiere.base/src/org/compiere/model/M_Element.java b/org.adempiere.base/src/org/compiere/model/M_Element.java index 0cd8e50b68..93df198787 100644 --- a/org.adempiere.base/src/org/compiere/model/M_Element.java +++ b/org.adempiere.base/src/org/compiere/model/M_Element.java @@ -20,6 +20,7 @@ import java.sql.ResultSet; import java.util.Properties; import java.util.logging.Level; +import org.adempiere.exceptions.DBException; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; @@ -192,7 +193,7 @@ public class M_Element extends X_AD_Element sql.append(" AND AD_Element_ID<>").append(get_ID()); int no = DB.getSQLValue(null, sql.toString(), columnName.toUpperCase()); if (no > 0) { - log.saveError("SaveErrorNotUnique", Msg.getElement(getCtx(), COLUMNNAME_ColumnName)); + log.saveError(DBException.SAVE_ERROR_NOT_UNIQUE_MSG, Msg.getElement(getCtx(), COLUMNNAME_ColumnName)); return false; } } diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java index 8f89a4aa14..b315c158f0 100644 --- a/org.adempiere.base/src/org/compiere/model/PO.java +++ b/org.adempiere.base/src/org/compiere/model/PO.java @@ -1963,7 +1963,6 @@ public abstract class PO * To reload call load() - not updated * @return true if saved */ - @SuppressWarnings("unused") public boolean save() { CLogger.resetLast(); @@ -2061,7 +2060,8 @@ public abstract class PO catch (Exception e) { log.log(Level.WARNING, "beforeSave - " + toString(), e); - log.saveError("Error", e, false); + String msg = DBException.getDefaultDBExceptionMessage(e); + log.saveError(msg != null ? msg : "Error", e, false); if (localTrx != null) { localTrx.rollback(); @@ -2139,9 +2139,11 @@ public abstract class PO } } } - catch (SQLException e) + catch (Exception e) { log.log(Level.WARNING, "afterSave - " + toString(), e); + String msg = DBException.getDefaultDBExceptionMessage(e); + log.saveError(msg != null ? msg : "Error", e); if (localTrx != null) { localTrx.rollback(); @@ -3110,6 +3112,8 @@ public abstract class PO } Trx localTrx = null; + Trx trx = null; + Savepoint savepoint = null; boolean success = false; try { @@ -3121,140 +3125,228 @@ public abstract class PO localTrx = Trx.get(localTrxName, true); m_trxName = localTrxName; } - - try - { - if (!beforeDelete()) + else { - log.warning("beforeDelete failed"); + trx = Trx.get(m_trxName, false); + if (trx == null) + { + // Using a trx that was previously closed or never opened + // Creating and starting the transaction right here, but please note + // that this is not a good practice + trx = Trx.get(m_trxName, true); + log.severe("Transaction closed or never opened ("+m_trxName+") => starting now --> " + toString()); + } + } + + try + { + // If not a localTrx we need to set a savepoint for rollback + if (localTrx == null) + savepoint = trx.setSavepoint(null); + + if (!beforeDelete()) + { + log.warning("beforeDelete failed"); + if (localTrx != null) + { + localTrx.rollback(); + } + else if (savepoint != null) + { + try { + trx.rollback(savepoint); + } catch (SQLException e) {} + savepoint = null; + } + return false; + } + } + catch (Exception e) + { + log.log(Level.WARNING, "beforeDelete", e); + String msg = DBException.getDefaultDBExceptionMessage(e); + log.saveError(msg != null ? msg : "Error", e, false); + if (localTrx != null) + { + localTrx.rollback(); + } + else if (savepoint != null) + { + try { + trx.rollback(savepoint); + } catch (SQLException e1) {} + savepoint = null; + } return false; } - } - catch (Exception e) - { - log.log(Level.WARNING, "beforeDelete", e); - log.saveError("Error", e, false); - // throw new DBException(e); - return false; - } - // Delete Restrict AD_Table_ID/Record_ID (Requests, ..) - String errorMsg = PO_Record.exists(AD_Table_ID, Record_ID, m_trxName); - if (errorMsg != null) - { - log.saveError("CannotDelete", errorMsg); - return false; - } - // Call ModelValidators TYPE_DELETE - errorMsg = ModelValidationEngine.get().fireModelChange - (this, isReplication() ? ModelValidator.TYPE_BEFORE_DELETE_REPLICATION : ModelValidator.TYPE_DELETE); - setReplication(false); // @Trifon - if (errorMsg != null) - { - log.saveError("Error", errorMsg); - return false; - } - - // - deleteTranslations(localTrxName); - // Delete Cascade AD_Table_ID/Record_ID (Attachments, ..) - PO_Record.deleteCascade(AD_Table_ID, Record_ID, localTrxName); - - // The Delete Statement - StringBuilder sql = new StringBuilder ("DELETE FROM ") //jz why no FROM?? - .append(p_info.getTableName()) - .append(" WHERE ") - .append(get_WhereClause(true)); - int no = 0; - if (isUseTimeoutForUpdate()) - no = DB.executeUpdateEx(sql.toString(), localTrxName, QUERY_TIME_OUT); - else - no = DB.executeUpdate(sql.toString(), localTrxName); - success = no == 1; - - // Save ID - m_idOld = get_ID(); - // - if (!success) - { - log.warning("Not deleted"); - if (localTrx != null) - localTrx.rollback(); - } - else - { - if (success) + // Delete Restrict AD_Table_ID/Record_ID (Requests, ..) + String errorMsg = PO_Record.exists(AD_Table_ID, Record_ID, m_trxName); + if (errorMsg != null) { - if( p_info.isChangeLog()) + log.saveError("CannotDelete", errorMsg); + if (localTrx != null) { - // Change Log - MSession session = MSession.get (p_ctx, false); - if (session == null) - log.fine("No Session found"); - else if (m_IDs.length == 1) - { - int AD_ChangeLog_ID = 0; - int size = get_ColumnCount(); - for (int i = 0; i < size; i++) - { - Object value = m_oldValues[i]; - if (value != null - && p_info.isAllowLogging(i) // logging allowed - && !p_info.isEncrypted(i) // not encrypted - && !p_info.isVirtualColumn(i) // no virtual column - && !"Password".equals(p_info.getColumnName(i)) - ) - { - // change log on delete - MChangeLog cLog = session.changeLog ( - m_trxName != null ? m_trxName : localTrxName, AD_ChangeLog_ID, - AD_Table_ID, p_info.getColumn(i).AD_Column_ID, - Record_ID, getAD_Client_ID(), getAD_Org_ID(), value, null, MChangeLog.EVENTCHANGELOG_Delete); - if (cLog != null) - AD_ChangeLog_ID = cLog.getAD_ChangeLog_ID(); - } - } // for all fields - } + localTrx.rollback(); + } + else if (savepoint != null) + { + try { + trx.rollback(savepoint); + } catch (SQLException e) {} + savepoint = null; + } + return false; + } + // Call ModelValidators TYPE_DELETE + errorMsg = ModelValidationEngine.get().fireModelChange + (this, isReplication() ? ModelValidator.TYPE_BEFORE_DELETE_REPLICATION : ModelValidator.TYPE_DELETE); + setReplication(false); // @Trifon + if (errorMsg != null) + { + log.saveError("Error", errorMsg); + if (localTrx != null) + { + localTrx.rollback(); + } + else if (savepoint != null) + { + try { + trx.rollback(savepoint); + } catch (SQLException e) {} + savepoint = null; + } + return false; + } - // Housekeeping - m_IDs[0] = I_ZERO; - if (m_trxName == null) - log.fine("complete"); - else - if (log.isLoggable(Level.FINE)) log.fine("[" + m_trxName + "] - complete"); - m_attachment = null; + try + { + // + deleteTranslations(localTrxName); + // Delete Cascade AD_Table_ID/Record_ID (Attachments, ..) + PO_Record.deleteCascade(AD_Table_ID, Record_ID, localTrxName); + + // The Delete Statement + StringBuilder sql = new StringBuilder ("DELETE FROM ") //jz why no FROM?? + .append(p_info.getTableName()) + .append(" WHERE ") + .append(get_WhereClause(true)); + int no = 0; + if (isUseTimeoutForUpdate()) + no = DB.executeUpdateEx(sql.toString(), localTrxName, QUERY_TIME_OUT); + else + no = DB.executeUpdate(sql.toString(), localTrxName); + success = no == 1; + } + catch (Exception e) + { + String msg = DBException.getDefaultDBExceptionMessage(e); + log.saveError(msg != null ? msg : e.getLocalizedMessage(), e); + success = false; + } + + // Save ID + m_idOld = get_ID(); + // + if (!success) + { + log.warning("Not deleted"); + if (localTrx != null) + { + localTrx.rollback(); + } + else if (savepoint != null) + { + try { + trx.rollback(savepoint); + } catch (SQLException e) {} + savepoint = null; } } else { - log.warning("Not deleted"); + if (success) + { + if( p_info.isChangeLog()) + { + // Change Log + MSession session = MSession.get (p_ctx, false); + if (session == null) + log.fine("No Session found"); + else if (m_IDs.length == 1) + { + int AD_ChangeLog_ID = 0; + int size = get_ColumnCount(); + for (int i = 0; i < size; i++) + { + Object value = m_oldValues[i]; + if (value != null + && p_info.isAllowLogging(i) // logging allowed + && !p_info.isEncrypted(i) // not encrypted + && !p_info.isVirtualColumn(i) // no virtual column + && !"Password".equals(p_info.getColumnName(i)) + ) + { + // change log on delete + MChangeLog cLog = session.changeLog ( + m_trxName != null ? m_trxName : localTrxName, AD_ChangeLog_ID, + AD_Table_ID, p_info.getColumn(i).AD_Column_ID, + Record_ID, getAD_Client_ID(), getAD_Org_ID(), value, null, MChangeLog.EVENTCHANGELOG_Delete); + if (cLog != null) + AD_ChangeLog_ID = cLog.getAD_ChangeLog_ID(); + } + } // for all fields + } + + // Housekeeping + m_IDs[0] = I_ZERO; + if (m_trxName == null) + log.fine("complete"); + else + if (log.isLoggable(Level.FINE)) log.fine("[" + m_trxName + "] - complete"); + m_attachment = null; + } + } + else + { + log.warning("Not deleted"); + } } - } - - try - { - success = afterDelete (success); - } - catch (Exception e) - { - log.log(Level.WARNING, "afterDelete", e); - log.saveError("Error", e, false); - success = false; - // throw new DBException(e); - } - - // Call ModelValidators TYPE_AFTER_DELETE - teo_sarca [ 1675490 ] - if (success) { - errorMsg = ModelValidationEngine.get().fireModelChange(this, ModelValidator.TYPE_AFTER_DELETE); - if (errorMsg != null) { - log.saveError("Error", errorMsg); + + try + { + success = afterDelete (success); + } + catch (Exception e) + { + log.log(Level.WARNING, "afterDelete", e); + String msg = DBException.getDefaultDBExceptionMessage(e); + log.saveError(msg != null ? msg : "Error", e, false); success = false; + // throw new DBException(e); + } + + // Call ModelValidators TYPE_AFTER_DELETE - teo_sarca [ 1675490 ] + if (success) { + errorMsg = ModelValidationEngine.get().fireModelChange(this, ModelValidator.TYPE_AFTER_DELETE); + if (errorMsg != null) { + log.saveError("Error", errorMsg); + success = false; + } } - } if (!success) { - if (localTrx != null) + if (localTrx != null) + { localTrx.rollback(); + } + else if (savepoint != null) + { + try { + trx.rollback(savepoint); + } catch (SQLException e) {} + savepoint = null; + } } else { @@ -3263,25 +3355,26 @@ public abstract class PO try { localTrx.commit(true); } catch (SQLException e) { - log.saveError("Error", e); + String msg = DBException.getDefaultDBExceptionMessage(e); + log.saveError(msg != null ? msg : "Error", e); success = false; } } } - // Reset - if (success) - { - //osgi event handler - Event event = EventManager.newEvent(IEventTopics.PO_POST_DELETE, this); - EventManager.getInstance().postEvent(event); - - m_idOld = 0; - int size = p_info.getColumnCount(); - m_oldValues = new Object[size]; - m_newValues = new Object[size]; - CacheMgt.get().reset(p_info.getTableName()); - } + // Reset + if (success) + { + //osgi event handler + Event event = EventManager.newEvent(IEventTopics.PO_POST_DELETE, this); + EventManager.getInstance().postEvent(event); + + m_idOld = 0; + int size = p_info.getColumnCount(); + m_oldValues = new Object[size]; + m_newValues = new Object[size]; + CacheMgt.get().reset(p_info.getTableName()); + } } finally { @@ -3290,8 +3383,20 @@ public abstract class PO localTrx.close(); m_trxName = null; } + else + { + if (savepoint != null) + { + try { + trx.releaseSavepoint(savepoint); + } catch (SQLException e) { + e.printStackTrace(); + } + } + savepoint = null; + trx = null; + } } - // log.info("" + success); return success; } // delete diff --git a/org.adempiere.base/src/org/compiere/util/DB.java b/org.adempiere.base/src/org/compiere/util/DB.java index ef345d48ef..1dd97303d1 100644 --- a/org.adempiere.base/src/org/compiere/util/DB.java +++ b/org.adempiere.base/src/org/compiere/util/DB.java @@ -1040,7 +1040,8 @@ public final class DB else { log.log(Level.SEVERE, cs.getSql() + " [" + trxName + "]", e); - log.saveError ("DBExecuteError", e); + String msg = DBException.getDefaultDBExceptionMessage(e); + log.saveError (msg != null ? msg : "DBExecuteError", e); } // throw new DBException(e); } diff --git a/org.adempiere.base/src/org/compiere/util/Trx.java b/org.adempiere.base/src/org/compiere/util/Trx.java index 8c0a663739..aa6cb8e03c 100644 --- a/org.adempiere.base/src/org/compiere/util/Trx.java +++ b/org.adempiere.base/src/org/compiere/util/Trx.java @@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; +import org.adempiere.exceptions.DBException; import org.compiere.Adempiere; import org.compiere.model.PO; @@ -369,6 +370,11 @@ public class Trx fireAfterCommitEvent(false); throw e; } + else + { + String msg = DBException.getDefaultDBExceptionMessage(e); + log.saveError(msg != null ? msg : e.getLocalizedMessage(), e); + } } m_active = false; fireAfterCommitEvent(false);