{"id":11684,"date":"2018-09-10T18:00:20","date_gmt":"2018-09-10T16:00:20","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/"},"modified":"2026-04-09T09:39:14","modified_gmt":"2026-04-09T07:39:14","slug":"using-triggers-in-repositories","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/","title":{"rendered":"Using a database trigger to request a rendition"},"content":{"rendered":"<p>Some time ago, a colleague asked around if someone knew a way to automatically request a rendition right after a document was checked in. This looked like a trigger to me and TBOs are here for that, right ? Sure but there was an additional condition: it should be set up by an administrator from the idql command-line tool as no programming was possible at that time on that system. Given that this tool, along with iapi, have been practically stagnant for years, that would be quite a surprise if it were possible at all. Admittedly, idql lets us invoke server administration methods but, according to the documentation, none of them deals directly with TBOs. Of course, I immediately thought of working at the database level and set up an INSERT or UPDATE trigger on the dm_document_s table (I suppose an Oracle database was used in that docbase; other RDBMS have equivalent concepts possibly with different implementations; the example code below was set up and tested in a repository&#8217;s Oracle schema), so let&#8217;s see how to do that. Of course, since we are bypassing the Documentum layer, the solution is a bit awkward but it looks simple and innocuous enough that no weirdness should be introduced in the repository.<\/p>\n<h3>Reminder: how to request a rendition<\/h3>\n<p>Usually, a rendition is explicitly requested by creating an entry in the dmi_queue_item table through the &#8220;queue&#8221; API function or its DfC counterpart:<br \/>\n<code><br \/>\nqueue,c,<em>doc_id<\/em>,dm_autorender_win31,rendition,0,F,,rendition_req_ps_pdf<br \/>\n<\/code><br \/>\nExample:<br \/>\n<code><br \/>\n?,c,select r_object_id from dm_document enable(return_top 10)<br \/>\nr_object_id<br \/>\n----------------<br \/>\n<strong>0900c350800001d0<\/strong><br \/>\n6700c35080000100<br \/>\n6700c35080000101<br \/>\n0900c350800001ff<br \/>\n0900c35080000200<br \/>\n0900c35080000201<br \/>\n0900c35080000202<br \/>\n0900c35080000203<br \/>\n0900c35080000204<br \/>\n0900c350800001da<br \/>\n(10 rows affected)<br \/>\n&nbsp;<br \/>\nAPI&gt; queue,c,<strong>0900c350800001d0<\/strong>,dm_autorender_win31,rendition,0,F,,rendition_req_ps_pdf<br \/>\n...<br \/>\n1b00c35080009504<br \/>\ndump,c,1b00c35080009504<br \/>\n...<br \/>\nUSER ATTRIBUTES<br \/>\n&nbsp;<br \/>\nname : dm_autorender_win31<br \/>\nstamp : 1b00c35080009504<br \/>\nsent_by : dmadmin<br \/>\ndate_sent : 8\/11\/2018 06:27:41<br \/>\ndue_date : nulldate<br \/>\nevent : rendition<br \/>\nitem_name : Default Signature Page Template<br \/>\nitem_id : 0900c350800001d0<br \/>\nitem_type : dm_esign_template<br \/>\ncontent_type : pdf<br \/>\nmessage : rendition_req_ps_pdf<br \/>\nrouter_id : 0000000000000000<br \/>\nsupervisor_name : dm_autorender_win31<br \/>\ntask_number :<br \/>\ntask_name : event<br \/>\ntask_type :<br \/>\ntask_state :<br \/>\ndependency_type :<br \/>\nnext_tasks_type :<br \/>\ninstruction_page : 0<br \/>\nplan_start_date : nulldate<br \/>\nactual_start_date : nulldate<br \/>\nread_flag : F<br \/>\ndelete_flag : F<br \/>\npriority : 0<br \/>\nposition : 0<br \/>\ndequeued_by :<br \/>\ndequeued_date : nulldate<br \/>\nsign_off_required : F<br \/>\nsign_off_user :<br \/>\nsign_off_date : nulldate<br \/>\nsource_docbase :<br \/>\ntarget_docbase :<br \/>\nremote_pending : F<br \/>\nsource_event : 0000000000000000<br \/>\nsource_stamp : 0<br \/>\ntask_subject :<br \/>\nevent_detail :<br \/>\n&nbsp;<br \/>\nSYSTEM ATTRIBUTES<br \/>\n&nbsp;<br \/>\nr_object_id : 1b00c35080009504<br \/>\n&nbsp;<br \/>\nAPPLICATION ATTRIBUTES<br \/>\n&nbsp;<br \/>\na_content_type :<br \/>\na_operations : queue<br \/>\n&nbsp;<br \/>\nINTERNAL ATTRIBUTES<br \/>\n&nbsp;<br \/>\ni_event_flags : 0<br \/>\ni_partition : 0<br \/>\ni_is_replica : F<br \/>\ni_vstamp : 0<br \/>\n<\/code><br \/>\nI voluntarily showed the whole generated queue entry because we&#8217;ll have to emulate it precisely with SQL later.<br \/>\nThere are other similar requests implemented as administrative methods, such as &#8220;transcode_content&#8221; for requesting a transformation of a content from one format into another by the media server and &#8220;register_asset&#8221; to request a thumbnail of a document. Those would be called through the &#8220;apply&#8221; API method, e.g.:<br \/>\n<code><br \/>\napply,c,<em>r_object_id<\/em>,transcode_content,message,S,<em>message<\/em>,source_format,S,<em>source_format<\/em>,target_format,S,<em>target_format<\/em><br \/>\napply,c,<em>r_object_id<\/em>,register_asset<br \/>\n<\/code><br \/>\nor in DQL:<br \/>\n<code><br \/>\nEXECUTE transcode_content FOR '<em>r_object_id<\/em>' WITH message='<em>message<\/em>',source_format='<em>format_name<\/em>', target_format=<em>format_name<\/em>'<br \/>\nEXECUTE register_asset FOR <em>object_id<\/em><br \/>\n<\/code><\/p>\n<h3>The SQL statement behind addqueue<\/h3>\n<p>If we activate SQL tracing, we can see what SQL statement the content server sends to the database:<br \/>\n<code><br \/>\ntrace,c,1,,SQL_TRACE<br \/>\n<\/code><br \/>\nand check the generated SQL statement, we notice that it looks as expected:<br \/>\n<code><br \/>\n2018-08-11T06:38:28.313756 27106[27106] 0100c3508000fd67 24 select r_object_type, i_vstamp, i_antecedent_id, i_branch_cnt, i_direct_dsc, r_immutable_flag, r_has_events, i_cabinet_id, r_link_cnt, r_frzn_assembly_cnt, r_access_date, i_latest_flag from dm_sysobject_s where r_object_id = :ID PARAMS :ID=0900c350800001d0<br \/>\n2018-08-11T06:38:28.314420 27106[27106] 0100c3508000fd67 24 EXEC 0.0006860000<br \/>\n2018-08-11T06:38:28.314467 27106[27106] 0100c3508000fd67 24 FETCH(1) 0.0000020000<br \/>\n2018-08-11T06:38:28.314620 27106[27106] 0100c3508000fd67 24 SELECT dm_dbalias_B.R_OBJECT_ID FROM dmtest.DM_GROUP_S dm_dbalias_B WHERE dm_dbalias_B.GROUP_NAME=:valp PARAMS :valp=dm_autorender_win31<br \/>\n2018-08-11T06:38:28.314953 27106[27106] 0100c3508000fd67 24 EXEC 0.0003500000<br \/>\n2018-08-11T06:38:28.314977 27106[27106] 0100c3508000fd67 24 FETCH(0) 0.0000010000<br \/>\n2018-08-11T06:38:28.315037 27106[27106] 0100c3508000fd67 24 select s.is_dynamic, s.group_class from dm_group_s s where s.group_name = :p0 PARAMS :p0=dm_autorender_win31<br \/>\n2018-08-11T06:38:28.315441 27106[27106] 0100c3508000fd67 24 EXEC 0.0004170000<br \/>\n2018-08-11T06:38:28.315463 27106[27106] 0100c3508000fd67 24 FETCH(0) 0.0000070000<br \/>\n<strong>2018-08-11T06:38:28.315584 27106[27106] 0100c3508000fd67 24 INSERT INTO dmtest.DMI_QUEUE_ITEM_S VALUES ('1b00c35080009509','dm_autorender_win31','1b00c35080009509','dmadmin',TO_DATE('2018\/08\/11.04.38.28','YYYY\/MM\/DD.HH24.MI.SS'),TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),'rendition','Default Signature Page Template','0900c350800001d0','dm_esign_template','pdf','rendition_req_ps_pdf','0000000000000000','dm_autorender_win31',' ','event',' ',' ',' ',' ', 0,TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),0,0, 0,0,' ',TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),0,' ',TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),' ','queue',' ',' ',0,'0000000000000000', 0,' ', 0,' ', 0,0, 0)<br \/>\n<\/strong><br \/>\n2018-08-11T06:38:28.317123 27106[27106] 0100c3508000fd67 24 EXEC 0.0015610000<br \/>\n2018-08-11T06:38:28.317173 27106[27106] 0100c3508000fd67 24 commit<br \/>\n<\/code><br \/>\nThe SQL INSERT statement exactly matches one to one the queue entry data that the dump showed before so we can easily reproduce it from within a database trigger.<br \/>\nHowever, the INSERT inserts the ID &#8216;1b00c35080009509&#8217; for the entry (twice, one as stampid and one as r_object_id; there is no evidence that those attributes may diverge at some point) but the SQL trace does not show its origin. Where does this id come from ? As a first approximation, I supposed that it was the next available number in the monotonically increasing sequence of the dmi_queue_item&#8217;s stamp id or r_object_id:<br \/>\n<code><br \/>\nselect max(r_object_id), max(stamp) from dmi_queue_item<br \/>\nmax(dmi_queue_item.r_object_id) max(dmi_queue_item.stamp)<br \/>\n------------------------------- -------------------------<br \/>\n1b00c35080009509 1b00c35080009509<br \/>\n(1 row affected)<br \/>\n<\/code><br \/>\nAnd thus the above preliminary query would be enough to get a value for the stampid\/r_object_id of the next dmi_queue_item&#8217;s entry to create (incremented by one, of course, and with the necessary precautions to avoid a race condition). But things are not so simple here. In a first version, I used this approach in the trigger but as soon as a traditional addqueue API statement was issued later, it failed with a uniqueness violation on the r_object_id column as if the API layer were not aware that the r_object_id it used had already been grabbed earlier.<br \/>\nThe process to get a new id is not fully documented; hints in relation to the type dmi_sequence can be found in the Knowledge Base (see e.g. <a title=\"How are data tickets generated?\" href=\"https:\/\/knowledge.opentext.com\/knowledge\/cs.dll\/kcs\/kbarticle\/view\/KB8675406\" target=\"_blank\" rel=\"noopener\">here<\/a>, <a title=\"What is the tag for various object types in Documentum Content Server?\" href=\"https:\/\/knowledge.opentext.com\/knowledge\/cs.dll\/kcs\/kbarticle\/view\/KB8669359\" target=\"_blank\" rel=\"noopener\">here<\/a>, and <a title=\"How do I find a dmi_sequence object for a type ?\" href=\"https:\/\/knowledge.opentext.com\/knowledge\/cs.dll\/kcs\/kbarticle\/view\/KB8758362\" target=\"_blank\" rel=\"noopener\">here<\/a>; an account at OpenText is needed to access those links) but it is still far from being usable.<br \/>\nI thought logically that some database sequence was used to generate the object ids, one dedicated sequence per doctype, but could find any in the repository&#8217;s schema. However, one of the links above suggests that internal sequences are still used in the guise of the type dmi_sequence. For each doctype, the attribute dmi_sequence.i_last_no holds the starting value of a chunk of available ids; this chunk gets initialized at each server restart but there is no persistent place where the used ids (or the last used one, or the next available one) are stored. As far as I can see, it looks like the latest used r_object_ids by doctype are kept in memory, probably in a semaphore-protected shared memory area so that Documentum child processes can access it quickly and concurrently, which is out of reach of an RDBMS process.<br \/>\nFortunately, a search on-line brought the following document <a title=\"EMC\u00ae Documentum\u00ae High-Volume Server\" href=\"https:\/\/www.google.com\/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=3&amp;ved=2ahUKEwjYwr6x-sndAhUBXSwKHV7RA6gQFjACegQICBAC&amp;url=http%3A%2F%2Fwww.howmuchinformation.org%2Fcollateral%2FTechnicalDocument%2Fdocu57890.pdf&amp;usg=AOvVaw01z4ObqsNuk5imuzmGTE3t\" target=\"_blank\" rel=\"noopener\">here.<\/a><br \/>\n<em>NEXT_ID_LIST<br \/>\nThis apply method reserves a list of object IDs from the repository.<br \/>\n&#8230;<br \/>\nEach ingested object requires a<br \/>\nunique object ID, and this method allows you to reserve a set of IDs. Once reserved, the IDs will not<br \/>\nbe used by the repository, so you will not ingest an object ID in use by another object.<br \/>\n&#8230;<br \/>\napply,c,NULL,NEXT_ID_LIST,TAG,I,08,HOW_MANY,I,100<br \/>\n<\/em><br \/>\nJust what the doctor ordered !<br \/>\nIn our case, we are dealing with dmi_queue_item. Its tag according to the System Object manual is 1b, i.e. 27.<br \/>\nExample of call:<br \/>\n<code><br \/>\napply,c,,NEXT_ID_LIST,TAG,I,<strong>27<\/strong>,HOW_MANY,I,1<br \/>\nnext,c,q0<br \/>\nget,c,q0,next_id<br \/>\n1b00c3508000ad21<br \/>\n<\/code><br \/>\nNote the 2-character type prefix in the returned id: 1b, i.e. 27 decimal, as requested.<br \/>\nThis call actually not only returns an id for the given type but also removes it from the pool of available ids in the chunk that is initialized by type in dmi_sequence.i_last_no at each server restart; said in other words, it officially consumes it. This resolves the issue we faced above.<br \/>\nSince this call is not available from within a database, we still need to get it from a Documentum client and pass it to the database trigger, which can be done easily by storing it into some unused attribute of dm_document before saving it. Here, we choose the attribute dm_document.LOG_ENTRY; its documented purpose is to store any user&#8217;s comment, so it kind of suits us well here without stretching too far its original raison d&#8217;\u00eatre. A custom doctype could even reserve a special, dedicated attribute for this usage.<br \/>\nIf log_entry is a no-go, an alternative but more complicated parameter-passing approach between the Documentum client and the database trigger could consist in using a database table, say ask_rendition(doc_id, queue_id).<\/p>\n<h3>The implementation<\/h3>\n<p>Now that all the stumbling blocks have been removed, the implementation is pretty straightforward: we create a trigger on the dm_sysobject_s table in the repository&#8217;s schema as follows:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: []\">create or replace trigger ask_rendition after insert or update on dm_sysobject_s for each row when (\n   (\n      new.r_object_id = '0900c350800001db'\n   ) and \n   (\n      new.r_object_type in ('dm_document')\n   ) and\n   (\n      new.a_content_type in ('crtext', 'doc', 'powerpoint', 'text', 'vsd') or \n      new.a_content_type like 'excel%' or\n      new.a_content_type like 'ppt%' or \n      new.a_content_type like 'msw%'\n   )\n)\nDECLARE\n   stampId DMI_QUEUE_ITEM_S.r_object_id%type;\n   format constant STRING(16) := 'XXXXXXXXXXXXXXXX';\nBEGIN\n   stampID := :new.LOG_ENTRY;\n   -- has a rendition been requested ?\n   -- if so, the LOG_ENTRY attribute must contain a dmi_queue_item id, and nothing else;\n   IF 0 = regexp_instr(stampID, '^1b[0-9a-f]{14}$') THEN\n      -- no rendition requested, quit now;\n      RETURN;\n   END IF;\n   INSERT INTO DMI_QUEUE_ITEM_S (\n                                    R_OBJECT_ID,\n                                    NAME,\n                                    STAMP,\n                                    SENT_BY,\n                                    DATE_SENT,\n                                    DUE_DATE,\n                                    EVENT,\n                                    ITEM_NAME,\n                                    ITEM_ID,\n                                    ITEM_TYPE,\n                                    CONTENT_TYPE,\n                                    MESSAGE,\n                                    ROUTER_ID,\n                                    SUPERVISOR_NAME,\n                                    TASK_NUMBER,\n                                    TASK_NAME,\n                                    TASK_TYPE,\n                                    TASK_STATE,\n                                    DEPENDENCY_TYPE,\n                                    NEXT_TASKS_TYPE,\n                                    INSTRUCTION_PAGE, \n                                    PLAN_START_DATE,\n                                    ACTUAL_START_DATE, \n                                    READ_FLAG,\n                                    DELETE_FLAG,\n                                    PRIORITY,\n                                    POSITION,\n                                    DEQUEUED_BY,\n                                    DEQUEUED_DATE,\n                                    SIGN_OFF_REQUIRED,\n                                    SIGN_OFF_USER,\n                                    SIGN_OFF_DATE,\n                                    A_CONTENT_TYPE,\n                                    A_OPERATIONS,\n                                    SOURCE_DOCBASE,\n                                    TARGET_DOCBASE,\n                                    REMOTE_PENDING,\n                                    SOURCE_EVENT,\n                                    SOURCE_STAMP,\n                                    TASK_SUBJECT, \n                                    I_EVENT_FLAGS,\n                                    EVENT_DETAIL,\n                                    I_PARTITION,\n                                    I_IS_REPLICA,\n                                    I_VSTAMP) \n                        VALUES (\n                                    stampId,\n                                    'dm_autorender_win31',\n                                    stampId,\n                                    'dmadmin',\n                                    sysdate,\n                                    TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),\n                                    'rendition',\n                                    :new.object_name,\n                                    :new.r_object_id,\n                                    :new.r_object_type,\n                                    :new.a_content_type,\n                                    'rendition_req_ps_pdf',\n                                    '0000000000000000',\n                                    'dm_autorender_win31',\n                                    ' ',\n                                    'event',\n                                    ' ',\n                                    ' ',\n                                    ' ',\n                                    ' ',         \n                                    0,\n                                    TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),\n                                    TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),\n                                    0,\n                                    0,         \n                                    0,\n                                    0,\n                                    ' ',\n                                    TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),\n                                    0,\n                                    ' ',\n                                    TO_DATE('0001\/01\/01.00.00.00','YYYY\/MM\/DD.HH24.MI.SS'),\n                                    ' ',\n                                    'queue',\n                                    ' ',\n                                    ' ',\n                                    0,\n                                    '0000000000000000',\n                                    0,\n                                    ' ',\n                                    0,\n                                    ' ',\n                                    0,\n                                    0,\n                                    0);\nEND;\n\/\nshow errors\n<\/pre>\n<p>Line 1 shows the kind of trigger we want. It will be fired right after a document is saved after an INSERT (i.e. it has just been created) or an UPDATE (i.e. is has just been modified). Note that the target table is dm_sysobject_s, not dm_document_s, because all the relevant attributes are stored in the former one. In Documentum&#8217;s object-relational model, dm_document inherits its attributes from dm_sysobject and in the model&#8217;s relational database implementation the inherited attributes come from dm_sysobject_s.<br \/>\nLines 2 to 4 can be removed as they are included for testing purpose only. However, they can be replaced by other constraints to better scope the set of documents that should be rendered, e.g. r_object_type set to some custom doctypes, owner_name != dmadmin to avoid system-generated documents.<br \/>\nLines 9 to 12 are restrictions on the content type; others types can be included if needed.<br \/>\nLine 19 extracts the id to use as the queue&#8217;s r_object_id\/stampid. As said above, we use the attribute LOG_ENTRY.<br \/>\nLines 20 to 25 check whether a rendition request has been requested; if so, dm_sysobject.log_entry must only contains a dmi_queue_item r_object_id (i.e. starting with 1b); any other value (or no value at all) is interpreted as no rendition request.<br \/>\nLines 26 to 117 set the values taken from the document into the queue&#8217;s entry columns.<br \/>\nLines 78, 94, 95, 101 and 104: this is how Documentum represents nulldates; we comply with it instead of storing NULLs.<br \/>\nAs shown, the trigger is fairly standard, no surprises here.<\/p>\n<h3>Usage<\/h3>\n<p>For the trigger to be activated, the attribute LOG_ENTRY must be initialized with the value returned by a call to NEXT_ID_LIST for a dmi_queue_item object; then, the document can be saved and as soon as this occurs, the triggers gets fired and inserts an entry for a rendition request into the queue.<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [10,19,28,45]\"># get an ID for the new queue entry;\nAPI&gt; apply,c,,NEXT_ID_LIST,TAG,I,27,HOW_MANY,I,1\n...\nq0\nAPI&gt; next,c,q0\n...\nOK\nAPI&gt; get,c,q0,next_id\n...\n1b00c3508000ad20\nAPI&gt; close,c,q0\n...\nOK\n\n# use document with id 0900c350800001db as test document;\n# set its LOG_ENTRY to that ID;\nfetch,c,0900c350800001db\nset,c,l,log_entry\n1b00c3508000ad20\nsave,c,l\n\n# the trigger is fired right away; check the newly queue entry;\ndump,c,1b00c3508000ad20\n...\nUSER ATTRIBUTES\n\n  name                            : dm_autorender_win31\n  stamp                           : 1b00c3508000ad20\n  sent_by                         : dmadmin\n  date_sent                       : 9\/16\/2018 14:17:20\n  due_date                        : nulldate\n  event                           : rendition\n  item_name                       : Blank PowerPoint Pre-3.0 Presentation\n  item_id                         : 0900c350800001db\n  item_type                       : dm_document\n  content_type                    : powerpoint\n  message                         : rendition_req_ps_pdf\n  router_id                       : 0000000000000000\n  supervisor_name                 : dm_autorender_win31\n...\n\n# enqueue a request through the traditional way;\nqueue,c,0900c350800001d0,dm_autorender_win31,rendition,0,F,,rendition_req_ps_pdf\n...\n1b00c3508000ad21\n\n# the next ID has been taken, no uniqueness violation;\n<\/pre>\n<p>If the document is updated but its LOG_ENTRY attribute has not been updated with a fresh value, the current id in LOG_ENTRY will be used to create a new entry in the queue, which will cause a uniqueness constraint violation and reported on stdout, e.g.:<br \/>\n<code><br \/>\nAPI&gt; fetch,c,0900c350800001db<br \/>\n...<br \/>\nOK<br \/>\nAPI&gt; dump,c,l<br \/>\n...<br \/>\nUSER ATTRIBUTES<br \/>\n&nbsp;<br \/>\nobject_name : Blank PowerPoint Pre-3.0 Presentation<br \/>\ntitle : TTT<br \/>\nsubject :<br \/>\nauthors []:<br \/>\nkeywords []:<br \/>\nresolution_label :<br \/>\nowner_name : dmadmin<br \/>\nowner_permit : 7<br \/>\ngroup_name : docu<br \/>\ngroup_permit : 5<br \/>\nworld_permit : 3<br \/>\nlog_entry : 1b00c3508000ad20<br \/>\n...<br \/>\nAPI&gt; set,c,l,title<br \/>\nSET&gt; Burn !<br \/>\n...<br \/>\nOK<br \/>\nAPI&gt; save,c,l<br \/>\n...<br \/>\n[DM_OBJ_MGR_E_SAVE_FAIL]error: \"save failed for object with handle 0900c350800001db of type dm_document: table on which save failed was DM_SYSOBJECT_S; error from database system was ORA-00001: unique constraint (DMTEST.D_1F00C3508000017B) violated<br \/>\nORA-06512: at \"DMTEST.ASK_RENDITION\", line 8<br \/>\nORA-04088: error during execution of trigger 'DMTEST.ASK_RENDITION'\"<br \/>\n&nbsp;<br \/>\n-- let's retry but with a new id this time;<br \/>\nAPI&gt; reset,c,l<br \/>\n...<br \/>\nOK<br \/>\nAPI&gt; apply,c,,NEXT_ID_LIST,TAG,I,27,HOW_MANY,I,1<br \/>\n...<br \/>\nq0<br \/>\nAPI&gt; next,c,q0<br \/>\n...<br \/>\nOK<br \/>\nAPI&gt; get,c,q0,next_id<br \/>\n...<br \/>\n1b00c3508000ad28<br \/>\nAPI&gt; set,c,l,log_entry<br \/>\nSET&gt; 1b00c3508000ad28<br \/>\n...<br \/>\nOK<br \/>\nAPI&gt; save,c,l<br \/>\n...<br \/>\nOK<br \/>\n-- any conflict ?<br \/>\nAPI&gt; queue,c,0900c350800001d0,dm_autorender_win31,rendition,0,F,,rendition_req_ps_pdf<br \/>\n...<br \/>\n1b00c3508000ad29<br \/>\n-- nope, it's fine;<br \/>\n<\/code><br \/>\nHowever, there are cases where a rendition is not necessary and therefore needs not be requested. In such cases, just leave log_entry empty or assign it a value that won&#8217;t match the regexp &#8216;^1b[0-9a-f]{14}&#8217; and the trigger will do nothing. This also allows to continue using log_entry as before (although utterly unlikely, it cannot be completely excluded that dmi_queue_item ids get involuntary assigned to this attribute at some point, which will be interpreted as a rendition request; in order to prevent this, just fool the regexp e.g. with a leading or trailing blank).<\/p>\n<h3>Conclusion<\/h3>\n<p>Usually, it is not recommended to bypass the Documentum API and directly access the underlying database but we do this all the time in queries and to fix the occasional object corruption. Besides, the implementation of Documentum&#8217;s object-relational model is well documented and Documentum let us also know the generated SQL statements it sends to the RDBMS. For simple, self-contained DML statements such as the solution&#8217;s INSERT into dmi_queue_item there should be no drawbacks.<br \/>\nBut there is another cleaner alternative: let the trigger invoke a java external procedure that uses the DfC. This could be the subject of a future blog.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some time ago, a colleague asked around if someone knew a way to automatically request a rendition right after a document was checked in. This looked like a trigger to me and TBOs are here for that, right ? Sure but there was an additional condition: it should be set up by an administrator from [&hellip;]<\/p>\n","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[198,525],"tags":[],"type_dbi":[],"class_list":["post-11684","post","type-post","status-publish","format-standard","hentry","category-database-management","category-enterprise-content-management"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Using a database trigger to request a rendition - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using a database trigger to request a rendition\" \/>\n<meta property=\"og:description\" content=\"Some time ago, a colleague asked around if someone knew a way to automatically request a rendition right after a document was checked in. This looked like a trigger to me and TBOs are here for that, right ? Sure but there was an additional condition: it should be set up by an administrator from [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-09-10T16:00:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-09T07:39:14+00:00\" \/>\n<meta name=\"author\" content=\"Middleware Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Middleware Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/\"},\"author\":{\"name\":\"Middleware Team\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/8d8563acfc6e604cce6507f45bac0ea1\"},\"headline\":\"Using a database trigger to request a rendition\",\"datePublished\":\"2018-09-10T16:00:20+00:00\",\"dateModified\":\"2026-04-09T07:39:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/\"},\"wordCount\":1688,\"commentCount\":0,\"articleSection\":[\"Database management\",\"Enterprise content management\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/\",\"name\":\"Using a database trigger to request a rendition - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"datePublished\":\"2018-09-10T16:00:20+00:00\",\"dateModified\":\"2026-04-09T07:39:14+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/8d8563acfc6e604cce6507f45bac0ea1\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/using-triggers-in-repositories\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using a database trigger to request a rendition\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/8d8563acfc6e604cce6507f45bac0ea1\",\"name\":\"Middleware Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"caption\":\"Middleware Team\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/middleware-team\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using a database trigger to request a rendition - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/","og_locale":"en_US","og_type":"article","og_title":"Using a database trigger to request a rendition","og_description":"Some time ago, a colleague asked around if someone knew a way to automatically request a rendition right after a document was checked in. This looked like a trigger to me and TBOs are here for that, right ? Sure but there was an additional condition: it should be set up by an administrator from [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/","og_site_name":"dbi Blog","article_published_time":"2018-09-10T16:00:20+00:00","article_modified_time":"2026-04-09T07:39:14+00:00","author":"Middleware Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Middleware Team","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/"},"author":{"name":"Middleware Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1"},"headline":"Using a database trigger to request a rendition","datePublished":"2018-09-10T16:00:20+00:00","dateModified":"2026-04-09T07:39:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/"},"wordCount":1688,"commentCount":0,"articleSection":["Database management","Enterprise content management"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/","url":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/","name":"Using a database trigger to request a rendition - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2018-09-10T16:00:20+00:00","dateModified":"2026-04-09T07:39:14+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/using-triggers-in-repositories\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using a database trigger to request a rendition"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1","name":"Middleware Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","caption":"Middleware Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/middleware-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11684","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=11684"}],"version-history":[{"count":1,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11684\/revisions"}],"predecessor-version":[{"id":41172,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11684\/revisions\/41172"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=11684"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=11684"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=11684"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=11684"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}