From 3bee3c94ac2953eb43d171390f36ac8ae9643458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Tak=C3=A1cs?= <93127072+PeterTakacs300@users.noreply.github.com> Date: Wed, 25 Oct 2023 10:11:40 +0200 Subject: [PATCH] IDEMPIERE-5886 - Add Foreign Key Constraint Error Message to AD_Column (#2069) * IDEMPIERE-5886 - Add Foreign Key Constraint Error Message to AD_Column * IDEMPIERE-5886 - small fixes * IDEMPIERE-5886 - pr2069PR patch Co-Authored-By: Carlos Ruiz --------- Co-authored-by: Carlos Ruiz --- .../oracle/202310171231_IDEMPIERE-5886.sql | 158 ++++++++++++++++++ .../202310171231_IDEMPIERE-5886.sql | 155 +++++++++++++++++ .../org/adempiere/exceptions/DBException.java | 32 +++- .../org/compiere/db/AdempiereDatabase.java | 20 +++ .../src/org/compiere/model/I_AD_Column.java | 11 ++ .../src/org/compiere/model/PO.java | 26 ++- .../src/org/compiere/model/X_AD_Column.java | 29 +++- .../src/org/compiere/util/CLogger.java | 27 +++ .../src/org/compiere/db/DB_Oracle.java | 6 + .../src/org/compiere/db/DB_PostgreSQL.java | 82 +++++++-- 10 files changed, 518 insertions(+), 28 deletions(-) create mode 100644 migration/iD11/oracle/202310171231_IDEMPIERE-5886.sql create mode 100644 migration/iD11/postgresql/202310171231_IDEMPIERE-5886.sql diff --git a/migration/iD11/oracle/202310171231_IDEMPIERE-5886.sql b/migration/iD11/oracle/202310171231_IDEMPIERE-5886.sql new file mode 100644 index 0000000000..9413fdeaff --- /dev/null +++ b/migration/iD11/oracle/202310171231_IDEMPIERE-5886.sql @@ -0,0 +1,158 @@ +-- IDEMPIERE-5886 +SELECT register_migration_script('202310171231_IDEMPIERE-5886.sql') FROM dual; + +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Oct 17, 2023, 12:34:25 PM CEST +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203842,0,0,'Y',TO_TIMESTAMP('2023-10-17 12:34:25','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-10-17 12:34:25','YYYY-MM-DD HH24:MI:SS'),100,'FKConstraintMsg_ID','Constraint Message','Constraint Message','D','33d8b6e4-5d70-4fdc-8517-3f4629258e05') +; + +-- Oct 17, 2023, 12:35:14 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (215961,0,'Constraint Message',101,'FKConstraintMsg_ID',10,'N','N','N','N','N',0,'N',30,102,0,0,'Y',TO_TIMESTAMP('2023-10-17 12:35:14','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-10-17 12:35:14','YYYY-MM-DD HH24:MI:SS'),100,203842,'Y','N','D','N','N','N','Y','4d4db0fc-1bbe-4117-b9d3-5d51df69a140','Y',0,'N','N','N') +; + +-- Oct 17, 2023, 12:35:18 PM CEST +UPDATE AD_Column SET FKConstraintName='FKConstraintMsg_ADColumn', FKConstraintType='N',Updated=TO_TIMESTAMP('2023-10-17 12:35:18','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=215961 +; + +-- Oct 17, 2023, 12:35:18 PM CEST +ALTER TABLE AD_Column ADD FKConstraintMsg_ID NUMBER(10) DEFAULT NULL +; + +-- Oct 17, 2023, 12:35:18 PM CEST +ALTER TABLE AD_Column ADD CONSTRAINT FKConstraintMsg_ADColumn FOREIGN KEY (FKConstraintMsg_ID) REFERENCES ad_message(ad_message_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Oct 17, 2023, 12:37:22 PM CEST +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (207775,'Constraint Message',101,215961,'Y',10,500,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-10-17 12:37:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-10-17 12:37:22','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','2da41a02-e961-42fd-b7ff-2aec7710bd82','Y',470,2) +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=230,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207143 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=240,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=59619 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=250,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204220 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=260,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=171 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=270,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2574 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=280,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2573 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=290,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=161 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=300,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=162 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=310,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202518 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=320,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202519 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=330, XPosition=1,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207775 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=340,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=160 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=350,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=166 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=360,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2370 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=370,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=10128 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=380,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5122 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=390,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207127 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=400,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=169 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=410,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=4941 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=420,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=50188 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=430,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=168 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=440,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=159 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=450,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=4940 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=460,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200288 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=470,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=56317 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=480,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=62467 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=490,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202257 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=500,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200648 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=510,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=167 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=520,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=825 +; + +-- Oct 17, 2023, 12:42:02 PM CEST +UPDATE AD_Field SET DisplayLogic='@AD_Reference_ID@=19 | @AD_Reference_ID@=30 | @AD_Reference_ID@=18 | @AD_Reference_ID@=21 | @AD_Reference_ID@=25 | @AD_Reference_ID@=31 | @AD_Reference_ID@=35 | @AD_Reference_ID@=33 | @AD_Reference_ID@=32 | @AD_Reference_ID@=53370 | @AD_Reference_ID@=200233 | @AD_Reference_ID@=200234 | @AD_Reference_ID@=200235', SeqNo=330,Updated=TO_TIMESTAMP('2023-10-17 12:42:02','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207775 +; + +-- Oct 24, 2023, 1:22:19 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','Record not deleted - there are dependent records in the table {0} for the column {1}',0,0,'Y',TO_TIMESTAMP('2023-10-24 13:22:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-10-24 13:22:19','YYYY-MM-DD HH24:MI:SS'),100,200838,'DeleteErrorDependentInfo','D','76cab20f-d155-45e9-b6e0-fd663312b180') +; + diff --git a/migration/iD11/postgresql/202310171231_IDEMPIERE-5886.sql b/migration/iD11/postgresql/202310171231_IDEMPIERE-5886.sql new file mode 100644 index 0000000000..6a63482bd3 --- /dev/null +++ b/migration/iD11/postgresql/202310171231_IDEMPIERE-5886.sql @@ -0,0 +1,155 @@ +-- IDEMPIERE-5886 +SELECT register_migration_script('202310171231_IDEMPIERE-5886.sql') FROM dual; + +-- Oct 17, 2023, 12:34:25 PM CEST +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203842,0,0,'Y',TO_TIMESTAMP('2023-10-17 12:34:25','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-10-17 12:34:25','YYYY-MM-DD HH24:MI:SS'),100,'FKConstraintMsg_ID','Constraint Message','Constraint Message','D','33d8b6e4-5d70-4fdc-8517-3f4629258e05') +; + +-- Oct 17, 2023, 12:35:14 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (215961,0,'Constraint Message',101,'FKConstraintMsg_ID',10,'N','N','N','N','N',0,'N',30,102,0,0,'Y',TO_TIMESTAMP('2023-10-17 12:35:14','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-10-17 12:35:14','YYYY-MM-DD HH24:MI:SS'),100,203842,'Y','N','D','N','N','N','Y','4d4db0fc-1bbe-4117-b9d3-5d51df69a140','Y',0,'N','N','N') +; + +-- Oct 17, 2023, 12:35:18 PM CEST +UPDATE AD_Column SET FKConstraintName='FKConstraintMsg_ADColumn', FKConstraintType='N',Updated=TO_TIMESTAMP('2023-10-17 12:35:18','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=215961 +; + +-- Oct 17, 2023, 12:35:18 PM CEST +ALTER TABLE AD_Column ADD COLUMN FKConstraintMsg_ID NUMERIC(10) DEFAULT NULL +; + +-- Oct 17, 2023, 12:35:18 PM CEST +ALTER TABLE AD_Column ADD CONSTRAINT FKConstraintMsg_ADColumn FOREIGN KEY (FKConstraintMsg_ID) REFERENCES ad_message(ad_message_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Oct 17, 2023, 12:37:22 PM CEST +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (207775,'Constraint Message',101,215961,'Y',10,500,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-10-17 12:37:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-10-17 12:37:22','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','2da41a02-e961-42fd-b7ff-2aec7710bd82','Y',470,2) +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=230,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207143 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=240,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=59619 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=250,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204220 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=260,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=171 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=270,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2574 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=280,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2573 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=290,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=161 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=300,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=162 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=310,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202518 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=320,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202519 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=330, XPosition=1,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207775 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=340,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=160 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=350,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=166 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=360,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2370 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=370,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=10128 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=380,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5122 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=390,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207127 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=400,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=169 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=410,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=4941 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=420,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=50188 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=430,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=168 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=440,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=159 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=450,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=4940 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=460,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200288 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=470,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=56317 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=480,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=62467 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=490,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202257 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=500,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=200648 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=510,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=167 +; + +-- Oct 17, 2023, 12:38:05 PM CEST +UPDATE AD_Field SET SeqNo=520,Updated=TO_TIMESTAMP('2023-10-17 12:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=825 +; + +-- Oct 17, 2023, 12:42:02 PM CEST +UPDATE AD_Field SET DisplayLogic='@AD_Reference_ID@=19 | @AD_Reference_ID@=30 | @AD_Reference_ID@=18 | @AD_Reference_ID@=21 | @AD_Reference_ID@=25 | @AD_Reference_ID@=31 | @AD_Reference_ID@=35 | @AD_Reference_ID@=33 | @AD_Reference_ID@=32 | @AD_Reference_ID@=53370 | @AD_Reference_ID@=200233 | @AD_Reference_ID@=200234 | @AD_Reference_ID@=200235', SeqNo=330,Updated=TO_TIMESTAMP('2023-10-17 12:42:02','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=207775 +; + +-- Oct 24, 2023, 1:22:19 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','Record not deleted - there are dependent records in the table {0} for the column {1}',0,0,'Y',TO_TIMESTAMP('2023-10-24 13:22:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-10-24 13:22:19','YYYY-MM-DD HH24:MI:SS'),100,200838,'DeleteErrorDependentInfo','D','76cab20f-d155-45e9-b6e0-fd663312b180') +; + diff --git a/org.adempiere.base/src/org/adempiere/exceptions/DBException.java b/org.adempiere.base/src/org/adempiere/exceptions/DBException.java index 1f7254a68d..752b46f529 100644 --- a/org.adempiere.base/src/org/adempiere/exceptions/DBException.java +++ b/org.adempiere.base/src/org/adempiere/exceptions/DBException.java @@ -18,8 +18,15 @@ package org.adempiere.exceptions; import java.sql.SQLException; +import org.compiere.model.MColumn; +import org.compiere.model.MMessage; +import org.compiere.model.MTable; +import org.compiere.model.Query; import org.compiere.util.CLogMgt; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.Util; /** @@ -43,6 +50,7 @@ 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 DELETE_ERROR_DEPENDENT_MSG_WITH_INFO = "DeleteErrorDependentInfo"; public static final String SAVE_ERROR_NOT_UNIQUE_MSG = "SaveErrorNotUnique"; private String m_sql = null; @@ -137,7 +145,8 @@ public class DBException extends AdempiereException return false; } else if (e instanceof SQLException) { - return ((SQLException)e).getErrorCode() == errorCode; + return ((SQLException)e).getErrorCode() == errorCode + || e.getMessage().contains("ORA-"+String.format("%05d", errorCode)+":"); } else if (e instanceof DBException) { SQLException sqlEx = ((DBException)e).getSQLException(); @@ -242,6 +251,27 @@ public class DBException extends AdempiereException if (isUniqueContraintError(e)) { return SAVE_ERROR_NOT_UNIQUE_MSG; } else if (isChildRecordFoundError(e)) { + // get constraint name from error message + String constraint = DB.getDatabase().getForeignKeyConstraint(e); + if (!Util.isEmpty(constraint)) { + // find the column with the constraint + MColumn fColumn = new Query(Env.getCtx(), MColumn.Table_Name, " UPPER(FKConstraintName) = UPPER(?) ", null) + .setParameters(constraint) + .first(); + if (fColumn != null) { + // get the dedicated message + int msgID = fColumn.getFKConstraintMsg_ID(); + if (msgID > 0) { + MMessage msgObj = MMessage.get(Env.getCtx(), msgID); + return msgObj.getValue(); + } else { + MTable fTable = MTable.get(fColumn.getAD_Table_ID()); + String msg = Msg.getMsg(Env.getCtx(), DELETE_ERROR_DEPENDENT_MSG_WITH_INFO, + new Object[] {fTable.get_Translation(MTable.COLUMNNAME_Name), fColumn.get_Translation(MColumn.COLUMNNAME_Name)}); + return msg; + } + } + } return DELETE_ERROR_DEPENDENT_MSG; } else if (isTimeout(e)) { return DATABASE_OPERATION_TIMEOUT_MSG; diff --git a/org.adempiere.base/src/org/compiere/db/AdempiereDatabase.java b/org.adempiere.base/src/org/compiere/db/AdempiereDatabase.java index b6661bb2ff..928811ed9a 100644 --- a/org.adempiere.base/src/org/compiere/db/AdempiereDatabase.java +++ b/org.adempiere.base/src/org/compiere/db/AdempiereDatabase.java @@ -334,6 +334,26 @@ public interface AdempiereDatabase public String getNameOfUniqueConstraintError(Exception e); + /** + *

+ * The "child record found error" contains the + * foreign key constraint name after the second occurrence + * of the opening double quote: ["]. + *

+ * + *

Example:

+ *

+ * ERROR: update or delete on table "m_product_category" + * violates foreign key constraint "mprodcategory_mdiscountsbreak" + * on table "m_discountschemabreak" + * Detail: Key (m_product_category_id)=(50000) is still referenced from table "m_discountschemabreak". + *

+ * + * @param e + * @return constraint name + */ + public String getForeignKeyConstraint(Exception e); + /** * @param columnName * @param csv comma separated value diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Column.java b/org.adempiere.base/src/org/compiere/model/I_AD_Column.java index d7575ec46c..91b0ba8122 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Column.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Column.java @@ -341,6 +341,17 @@ s active status or processed status. This logic Applicable only if Always Updata */ public int getFieldLength(); + /** Column name FKConstraintMsg_ID */ + public static final String COLUMNNAME_FKConstraintMsg_ID = "FKConstraintMsg_ID"; + + /** Set Constraint Message */ + public void setFKConstraintMsg_ID (int FKConstraintMsg_ID); + + /** Get Constraint Message */ + public int getFKConstraintMsg_ID(); + + public org.compiere.model.I_AD_Message getFKConstraintMsg() throws RuntimeException; + /** Column name FKConstraintName */ public static final String COLUMNNAME_FKConstraintName = "FKConstraintName"; diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java index fba07f3f16..ce509d354b 100644 --- a/org.adempiere.base/src/org/compiere/model/PO.java +++ b/org.adempiere.base/src/org/compiere/model/PO.java @@ -4225,7 +4225,10 @@ public abstract class PO localTrx.commit(true); } catch (SQLException e) { String msg = DBException.getDefaultDBExceptionMessage(e); - log.saveError(msg != null ? msg : "Error", e); + if (msg != null) + log.saveError(msg, msg, e, false); + else + log.saveError("Error", e, false); success = false; } } @@ -5659,21 +5662,16 @@ public abstract class PO boolean found = false; String dbIndexName = DB.getDatabase().getNameOfUniqueConstraintError(e); if (log.isLoggable(Level.FINE)) log.fine("dbIndexName=" + dbIndexName); - MTableIndex[] indexes = MTableIndex.get(MTable.get(getCtx(), get_Table_ID())); - for (MTableIndex index : indexes) + MTableIndex index = new Query(getCtx(), MTableIndex.Table_Name, "AD_Table_ID=? AND UPPER(Name)=UPPER(?)", null) + .setParameters(get_Table_ID(), dbIndexName) + .setOnlyActiveRecords(true) + .first(); + if (index != null && index.getAD_Message_ID() > 0) { - if (dbIndexName.equalsIgnoreCase(index.getName())) - { - if (index.getAD_Message_ID() > 0) - { - MMessage message = MMessage.get(getCtx(), index.getAD_Message_ID()); - log.saveError("SaveError", Msg.getMsg(getCtx(), message.getValue())); - found = true; - } - break; - } + MMessage message = MMessage.get(getCtx(), index.getAD_Message_ID()); + log.saveError("SaveError", Msg.getMsg(getCtx(), message.getValue())); + found = true; } - if (!found) log.saveError(msg, info); } diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Column.java b/org.adempiere.base/src/org/compiere/model/X_AD_Column.java index dc9c762332..64f0b384de 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Column.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Column.java @@ -33,7 +33,7 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent /** * */ - private static final long serialVersionUID = 20230505L; + private static final long serialVersionUID = 20231019L; /** Standard Constructor */ public X_AD_Column (Properties ctx, int AD_Column_ID, String trxName) @@ -645,6 +645,33 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent return ii.intValue(); } + public org.compiere.model.I_AD_Message getFKConstraintMsg() throws RuntimeException + { + return (org.compiere.model.I_AD_Message)MTable.get(getCtx(), org.compiere.model.I_AD_Message.Table_ID) + .getPO(getFKConstraintMsg_ID(), get_TrxName()); + } + + /** Set Constraint Message. + @param FKConstraintMsg_ID Constraint Message + */ + public void setFKConstraintMsg_ID (int FKConstraintMsg_ID) + { + if (FKConstraintMsg_ID < 1) + set_Value (COLUMNNAME_FKConstraintMsg_ID, null); + else + set_Value (COLUMNNAME_FKConstraintMsg_ID, Integer.valueOf(FKConstraintMsg_ID)); + } + + /** Get Constraint Message. + @return Constraint Message */ + public int getFKConstraintMsg_ID() + { + Integer ii = (Integer)get_Value(COLUMNNAME_FKConstraintMsg_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + /** Set Constraint Name. @param FKConstraintName Constraint Name */ diff --git a/org.adempiere.base/src/org/compiere/util/CLogger.java b/org.adempiere.base/src/org/compiere/util/CLogger.java index 0b93a8fe7a..74bccd0998 100644 --- a/org.adempiere.base/src/org/compiere/util/CLogger.java +++ b/org.adempiere.base/src/org/compiere/util/CLogger.java @@ -164,6 +164,33 @@ public class CLogger extends Logger return saveError (AD_Message, ex.getLocalizedMessage(), issueError); } // saveError + /** + * Set and issue Error and save as ValueNamePair + * @param AD_Message message key + * @param message + * @param ex exception + * @return true (to avoid removal of method) + */ + public boolean saveError (String AD_Message, String message, Exception ex) + { + Env.getCtx().put(LAST_EXCEPTION, ex); + return saveError (AD_Message, message, true); + } // saveError + + /** + * Set and issue (if specified) Error and save as ValueNamePair + * @param AD_Message message key + * @param message + * @param ex exception + * @param issueError if true will issue an error + * @return true (to avoid removal of method) + */ + public boolean saveError (String AD_Message, String message, Exception ex, boolean issueError) + { + Env.getCtx().put(LAST_EXCEPTION, ex); + return saveError (AD_Message, message, issueError); + } // saveError + /** * Set Error and save as ValueNamePair * @param AD_Message message key diff --git a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java index 48769404b3..9a33bad971 100644 --- a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java +++ b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java @@ -950,6 +950,12 @@ public class DB_Oracle implements AdempiereDatabase return info.substring(fromIndex + 1, toIndex); } + @Override + public String getForeignKeyConstraint(Exception e) { + // finding the name of foreign key constraint is the same as unique constraint + return getNameOfUniqueConstraintError(e); + } + @Override public String subsetClauseForCSV(String columnName, String csv) { StringBuilder builder = new StringBuilder(); diff --git a/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java b/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java index 5f014fbf0b..4bd416b31a 100755 --- a/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java +++ b/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java @@ -84,7 +84,11 @@ public class DB_PostgreSQL implements AdempiereDatabase private static final String POOL_PROPERTIES = "hikaricp.properties"; private static Boolean sysNative = null; - + + final static char DOUBLE_QUOTE = '"'; + final static char ANGLED_QUOTE_LEFT = '\u00ab'; // « + final static char ANGLED_QUOTE_RIGHT = '\u00bb'; // » + static { String property = SystemProperties.getPostgreSQLNative(); @@ -1019,20 +1023,74 @@ public class DB_PostgreSQL implements AdempiereDatabase return false; } + /** + * Get the name of the unique constraint name based on a postgresql message + * This method works for English, Spanish and German + * The foreign key constraint name is expected to be found in the second quoted string + * English quotes -> "constraint" + * Spanish quotes -> «constraint» + * German quotes -> »constraint« + */ @Override public String getNameOfUniqueConstraintError(Exception e) { String info = e.getMessage(); - int fromIndex = info.indexOf("\""); - if (fromIndex == -1) - fromIndex = info.indexOf("\u00ab"); // quote for spanish postgresql message - if (fromIndex == -1) - return info; - int toIndex = info.indexOf("\"", fromIndex + 1); - if (toIndex == -1) - toIndex = info.indexOf("\u00bb", fromIndex + 1); - if (toIndex == -1) - return info; - return info.substring(fromIndex + 1, toIndex); + int start = -1; + int end = -1; + boolean open = false; + for (int idx = 0; idx < info.length(); idx++) { + if ( info.charAt(idx) == DOUBLE_QUOTE + || info.charAt(idx) == ANGLED_QUOTE_LEFT + || info.charAt(idx) == ANGLED_QUOTE_RIGHT) { + open = !open; + if (open) { + start = idx; + } else { + end = idx; + break; + } + } + } + if (end != -1) + return info.substring(start+1, end); + return null; + } + + /** + * Get the foreign key constraint name based on a postgresql message + * This method works for English, Spanish and German + * The foreign key constraint name is expected to be found in the second quoted string + * English quotes -> "constraint" + * Spanish quotes -> «constraint» + * German quotes -> »constraint« + */ + @Override + public String getForeignKeyConstraint(Exception e) { + String info = e.getMessage(); + int start = -1; + int end = -1; + int cntword = 0; + boolean open = false; + for (int idx = 0; idx < info.length(); idx++) { + if ( info.charAt(idx) == DOUBLE_QUOTE + || info.charAt(idx) == ANGLED_QUOTE_LEFT + || info.charAt(idx) == ANGLED_QUOTE_RIGHT) { + open = !open; + if (open) { + cntword++; + } + if (cntword == 2) { + if (open) { + start = idx; + } else { + end = idx; + break; + } + } + } + } + if (end != -1) + return info.substring(start+1, end); + return null; } @Override