Hello,
Just a post concerning the immutable document : Documentum doesn’t allow the modification of an immutable document:
1 | DQL> SELECT r_object_id, status, r_immutable_flag FROM my_huo_type WHERE ref_document = 'JavaLu_test_immutable' ; |
2 | r_object_id status r_immutable_flag |
3 | ================ ====== ====== |
If, we try to change the status attribute of this document, we will obtain the following error:
1 | DQL> 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 :
1 | DQL> SELECT r_immutable_flag from my_huo_type where r_object_id = '090xxxxxxxxxxxx8' ; |
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
1 | DQL> EXECUTE exec_sql WITH query= 'update dm_sysobject_s set r_immutable_flag=0 where r_object_id= ' '090xxxxxxxxxxxx8' '' ; |
3 | DQL> 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
1 | DQL> UPDATE my_huo_type OBJECTS set status=6 where r_object_id = '090xxxxxxxxxxxx8' ; |
- Update the flag r_immutable_flag=TRUE (previous value) via DQL
1 | DQL> EXECUTE exec_sql WITH query= 'update dm_sysobject_s set r_immutable_flag=1 where r_object_id= ' '090xxxxxxxxxxxx8' '' ; |
3 | DQL> 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
1 | APi> set ,c,090xxxxxxxxxxxx8,r_immutable_flag |
- Update the target « status » attribute via API
1 | API> set ,c,090xxxxxxxxxxxx8,status |
- Update the flag r_immutable_flag=TRUE (previous value) via API
1 | API> set ,c,090xxxxxxxxxxxx8,r_immutable_flag |
- Save the document via API
1 | API>save,c,090xxxxxxxxxxxx8 |
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.
01 | select 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' ); |
03 | r_object_id = 6axxxxxxxxxxxxxxa0 |
04 | type_name = my_huo_type |
10 | r_object_id = 6ayyyyyyyyyyyyyy87 |
11 | type_name = my_huo_type |
12 | label_text = status_free_to_change |
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.
1 | update 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 :
2 | DQL> SELECT mytype.r_version_label, mytype.r_lock_owner, mytype.r_object_id, mytype.status, mytype.acl_domain, mytype.acl_name |
3 | FROM my_huo_type ( ALL ) mytype WHERE mytype.ref_doc = 'JavaLu_test_immutable' |
4 | order by r_creation_date desc , r_version_label desc ENABLE (ROW_BASED); |
8 | API>unlock,c,090xxxxxxxxxxc1 |
In practice via DFC / Java code:
EXAMPLE 1 : Simple example
01 | for (String documentId : documentIds) { |
03 | LOGGER.info(documentId + " : update content (" + countCurrent + "/" + countTotal + ")... " ); |
04 | IDfDocument document = (IDfDocument) session.getObject( new DfId(documentId)); |
05 | boolean isImmutable = document.isImmutable(); |
07 | document.setBoolean( "r_immutable_flag" , false ); |
11 | document.setSubject(SUBJECT_ANONYMIZED); |
12 | document.setContentType( "pdf" ); |
13 | document.setFile(docFolder + File.separator + canal + "-encrypted.pdf" ); |
17 | document.setBoolean( "r_immutable_flag" , true ); |
20 | LOGGER.info(documentId + " : [OK]" ); |
21 | } catch (Exception e) { |
22 | LOGGER.error(documentId + " : [KO: error to update content]" , e); |
EXAMPLE 2 : Complete example with transaction and rollback on last modifier, last modification date and immutable flag
01 | private 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" ); |
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); |
15 | IDfValue dfValue = coll.getValueAt( 0 ); |
16 | if (!dfValue.asBoolean()) { |
17 | throw new RuntimeException( "" ); |
20 | throw new RuntimeException( "" ); |
…..
01 | private 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" ); |
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); |
12 | IDfValue dfValue = coll.getValueAt( 0 ); |
13 | if (!dfValue.asBoolean()) { |
14 | throw new RuntimeException( "" ); |
17 | throw new RuntimeException( "" ); |
…..
01 | IDfSession session = ...; |
02 | IDfCollection documents = ...; |
04 | while (documents.next()) { |
05 | String currObjectId = null ; |
06 | boolean previousImmutableFlag = false ; |
08 | boolean isTransactionalSession = false ; |
09 | boolean noErrorWithCurrentDocument = false ; |
11 | if (!session.isTransactionActive()) { |
13 | isTransactionalSession = true ; |
16 | currObjectId = documents.getString( "r_object_id" ); |
18 | IDfTime previousModifyDateTime = documents.getTime( "r_modify_date" ); |
19 | String previousModifier = documents.getString( "r_modifier" ); |
20 | String aContentType = documents.getString( "a_content_type" ); |
21 | previousImmutableFlag = documents.getBoolean( "r_immutable_flag" ); |
24 | if (previousImmutableFlag){ |
25 | setValuesToImmutableAttributeBySQL(session, currObjectId, false ); |
33 | setPreviousValuesOfLastModifAttributesBySQL(session, currObjectId, previousModifyDateTime, previousModifier); |
35 | noErrorWithCurrentDocument = true ; |
36 | } catch (Throwable th) { |
37 | Throwable rootCause = ExceptionUtils.getRootCause(th); |
39 | rootCause.printStackTrace(pw); |
41 | th.printStackTrace(pw); |
46 | if (previousImmutableFlag){ |
47 | setValuesToImmutableAttributeBySQL(session, currObjectId, true ); |
50 | if (isTransactionalSession) { |
51 | if (noErrorWithCurrentDocument) { |
52 | session.commitTrans(); |
That’s all!!!!
Huseyin OZVEREN
Related