JavaBlog.fr / Java.lu API DCTM,DEVELOPMENT,Documentum,DQL DCTM Documentum : Modify/Change Immutable Document

Documentum : Modify/Change Immutable Document

Hello,

Just a post concerning the immutable document : Documentum doesn’t allow the modification of an immutable document:

1DQL> SELECT r_object_id, status, r_immutable_flag FROM my_huo_type WHERE ref_document = 'JavaLu_test_immutable';
2r_object_id       status  r_immutable_flag
3================  ======  ======
4090xxxxxxxxxxxx8  1       1                  
5(1 rows affected)

If, we try to change the status attribute of this document, we will obtain the following error:

1DQL> UPDATE my_huo_type OBJECTS set status=6 where r_object_id ='090xxxxxxxxxxxx8';
2[DM_QUERY_F_UP_SAVE]fatal:  "UPDATE:  An error has occurred during a save operation."
3[DM_SYSOBJECT_E_CANT_SAVE_IMMUTABLE]error:  "Cannot save MY_DOC_OBJ_NAME_1 since it is immutable."

However, even on an immutable document, some attributes/actions could be done: change of ACL, content moving, modification done via SQL instructions like last modification date,…etc.

When the above error occurs, the simple « workarround solution » is:
1. set the r_immutable_flag attribute to FALSE,
2. do the modifications on the document,
3. finally set again the r_immutable_flag attribute to its previous TRUE value.

 
Here, the steps of this « workarround solution »:
1. Check the value of r_immutable_flag attributwe of the document :

1DQL> SELECT r_immutable_flag from my_huo_type where r_object_id ='090xxxxxxxxxxxx8';
2r_immutable_flag 
3

 
 
2. IF r_immutable_flag=TRUE OR r_immutable_flag=1 THEN,
Solution 1 : via DQL

  • Update the flag r_immutable_flag=FALSE via DQL
    1DQL> EXECUTE exec_sql WITH query= 'update dm_sysobject_s set r_immutable_flag=0 where r_object_id= ''090xxxxxxxxxxxx8''';
    2OR
    3DQL> EXECUTE exec_sql WITH query= 'update dm_sysobject_s set r_immutable_flag=''F'' where r_object_id= ''090xxxxxxxxxxxx8''';
  • Update the target « status » attribute via DQL
    1DQL> UPDATE my_huo_type OBJECTS set status=6 where r_object_id ='090xxxxxxxxxxxx8';
  • Update the flag r_immutable_flag=TRUE (previous value) via DQL
    1DQL> EXECUTE exec_sql WITH query= 'update dm_sysobject_s set r_immutable_flag=1 where r_object_id= ''090xxxxxxxxxxxx8''';
    2OR
    3DQL> EXECUTE exec_sql WITH query= 'update dm_sysobject_s set r_immutable_flag=''T'' where r_object_id= ''090xxxxxxxxxxxx8''';

 
 
Solution 2 : via API

  • Update the flag r_immutable_flag=FALSE via API
    1APi>set,c,090xxxxxxxxxxxx8,r_immutable_flag
    20
    3...
    4OK
  • Update the target « status » attribute via API
    1API>set,c,090xxxxxxxxxxxx8,status
    26
    3...
    4OK
  • Update the flag r_immutable_flag=TRUE (previous value) via API
    1API>set,c,090xxxxxxxxxxxx8,r_immutable_flag
    21
    3...
    4OK
  • Save the document via API
    1API>save,c,090xxxxxxxxxxxx8
    2...
    3OK

 
 
Solution 3 : Change the behaviour of docbase in order to ignore value of the r_immutable_flag flag when the ‘status’ attribute of the type ‘my_huo_type’ is modified.

01select r_object_id, type_name, label_text, nls_key, i_ignore_immutable, ignore_immutable from  dmi_dd_attr_info where type_name = 'my_huo_type' and attr_name IN ('status','status_free_to_change');
02 
03r_object_id = 6axxxxxxxxxxxxxxa0
04type_name = my_huo_type
05label_text = status
06nls_key = en
07i_ignore_immutable = 0
08ignore_immutable = 0
09 
10r_object_id = 6ayyyyyyyyyyyyyy87
11type_name = my_huo_type
12label_text = status_free_to_change
13nls_key = en
14i_ignore_immutable = 0
15ignore_immutable = 1

The value of the dmi_dd_attr_info.ignore_immutable determines if the attribute is free for changes even if the object is immutable. In either case i_ignore_immutable doesn’t make any difference. In the above example the status_free_to_change attribute is free for changes.

1update dmi_dd_attr_info object set ignore_immutable = T where type_name = 'my_huo_type' and attr_name = 'status';

 
 
3. ELSE (IF r_immutable_flag=FALSE OR r_immutable_flag=0 THEN),

  • See the logs,
  • Check if the target version of document is lock :
    1# Get the all versions
    2DQL>SELECT mytype.r_version_label, mytype.r_lock_owner, mytype.r_object_id, mytype.status, mytype.acl_domain, mytype.acl_name
    3FROM my_huo_type (ALL) mytype WHERE mytype.ref_doc = 'JavaLu_test_immutable' 
    4order by r_creation_date desc, r_version_label desc ENABLE (ROW_BASED);
    5...
    6 
    7# unlock the version
    8API>unlock,c,090xxxxxxxxxxc1
    9...etc

 
 
In practice via DFC / Java code:
 
EXAMPLE 1 : Simple example

01for (String documentId : documentIds) {
02    try {
03        LOGGER.info(documentId + " : update content (" + countCurrent + "/" + countTotal + ")... ");
04        IDfDocument document = (IDfDocument) session.getObject(new DfId(documentId));
05        boolean isImmutable = document.isImmutable();
06        if (isImmutable) {
07            document.setBoolean("r_immutable_flag", false);
08            document.save();
09        }
10         
11        document.setSubject(SUBJECT_ANONYMIZED);
12        document.setContentType("pdf");
13        document.setFile(docFolder + File.separator + canal + "-encrypted.pdf");
14        document.save();
15         
16        if (isImmutable) {
17            document.setBoolean("r_immutable_flag", true);
18            document.save();
19        }
20        LOGGER.info(documentId + " : [OK]");
21    } catch(Exception e) {
22        LOGGER.error(documentId + " : [KO: error to update content]", e);
23    }
24    countCurrent++;
25}

 
 
EXAMPLE 2 : Complete example with transaction and rollback on last modifier, last modification date and immutable flag

01private void setPreviousValuesOfLastModifAttributesBySQL(IDfSession session, String currObjectId, IDfTime previousModifyDateTime, String previousModifier) throws Throwable{
02    StringBuilder sql = new StringBuilder();
03    sql.append("UPDATE ").append(session.getDocbaseOwnerName()).append(".DM_SYSOBJECT_S");
04    sql.append(" SET ");
05    sql.append(" R_MODIFIER = '").append(previousModifier).append("',");
06    DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
07    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
08    sql.append(" R_MODIFY_DATE = to_date('").append(dateFormat.format(previousModifyDateTime.getDate())).append("', 'DD-MM-YYYY HH24:MI:SS')");
09    sql.append(" WHERE R_OBJECT_ID = '").append(currObjectId).append("'");
10    IDfApplyExecSQL dfApplyExecSQL = (IDfApplyExecSQL) DfAdminCommand.getCommand(DfAdminCommand.APPLY_EXEC_SQL);
11    dfApplyExecSQL.setQuery(sql.toString());
12    IDfCollection coll = dfApplyExecSQL.execute(session);
13    try {
14        if (coll.next()) {
15            IDfValue dfValue = coll.getValueAt(0);
16            if (!dfValue.asBoolean()) {
17                throw new RuntimeException("");
18            }
19        } else {
20            throw new RuntimeException("");
21        }
22    } finally {
23        if(coll!=null){
24            coll.close();
25        }
26    }
27}

…..

01private void setValuesToImmutableAttributeBySQL(IDfSession session, String currObjectId, boolean bValue) throws Throwable{
02    StringBuilder sql = new StringBuilder();
03    sql.append("UPDATE ").append(session.getDocbaseOwnerName()).append(".DM_SYSOBJECT_S");
04    sql.append(" SET ");
05    sql.append(" R_IMMUTABLE_FLAG = '").append(bValue?"1":"0").append("' ");
06    sql.append(" WHERE R_OBJECT_ID = '").append(currObjectId).append("'");
07    IDfApplyExecSQL dfApplyExecSQL = (IDfApplyExecSQL) DfAdminCommand.getCommand(DfAdminCommand.APPLY_EXEC_SQL);
08    dfApplyExecSQL.setQuery(sql.toString());
09    IDfCollection coll = dfApplyExecSQL.execute(session);
10    try {
11        if (coll.next()) {
12            IDfValue dfValue = coll.getValueAt(0);
13            if (!dfValue.asBoolean()) {
14                throw new RuntimeException("");
15            }
16        } else {
17            throw new RuntimeException("");
18        }
19    } finally {
20        if(coll!=null){
21            coll.close();
22        }
23    }
24}

…..

01IDfSession session = ...;
02IDfCollection documents = ...;
03 
04while (documents.next()) {
05    String currObjectId = null;
06    boolean previousImmutableFlag = false;
07 
08    boolean isTransactionalSession = false;
09    boolean noErrorWithCurrentDocument = false;
10    try {
11        if (!session.isTransactionActive()) {
12            session.beginTrans();
13            isTransactionalSession = true;
14        }
15         
16        currObjectId = documents.getString("r_object_id");
17        // Get and store the value of r_modify_date AND r_modifier BEFORE the changes
18        IDfTime previousModifyDateTime = documents.getTime("r_modify_date");
19        String previousModifier = documents.getString("r_modifier");
20        String aContentType = documents.getString("a_content_type"); // excel12book
21        previousImmutableFlag = documents.getBoolean("r_immutable_flag");
22 
23        //Mise à jour du flag « r_immutable_flag=FALSE » via SQL
24        if(previousImmutableFlag){
25            setValuesToImmutableAttributeBySQL(session, currObjectId, false);
26        }
27 
28        // #### Appying changements
29        //....
30         
31        // Setting of the previous value for r_modify_date AND r_modifier because the attachment of aspect needs a SAVE action on document.
32        // So, Content server overrides r_modifer and r_modify_date informations.
33        setPreviousValuesOfLastModifAttributesBySQL(session, currObjectId, previousModifyDateTime, previousModifier);
34         
35        noErrorWithCurrentDocument = true;
36    } catch(Throwable th) {
37        Throwable rootCause = ExceptionUtils.getRootCause(th);
38        if(rootCause!=null){
39            rootCause.printStackTrace(pw);
40        }else{
41            th.printStackTrace(pw);
42        }
43        throw th;
44    }finally{
45        //Mise à jour du flag « r_immutable_flag=TRUE » via SQL
46        if(previousImmutableFlag){
47            setValuesToImmutableAttributeBySQL(session, currObjectId, true);
48        }
49 
50        if (isTransactionalSession) {
51            if (noErrorWithCurrentDocument) {
52                session.commitTrans();
53            } else {
54                session.abortTrans();
55            }
56        }
57    }
58}// end-while

That’s all!!!!

Huseyin OZVEREN

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.

Related Post