Message Boards

change content in XML database

sunil kumar, modified 6 Years ago.

change content in XML database

New Member Posts: 13 Join Date: 3/28/17 Recent Posts
hi all,
I want to change the XML data of content in journal article table.
i know liferay recommend to do this using liferay API , but i have to do this.
i got the XML as string using select query of SQL.
result is as :
"<?xml version="1.0"?>
<root available-locales="en_US" default-locale="en_US">
<dynamic-element name="news" type="text" index-type="keyword" index="0">
<dynamic-content language-id="en_US"><![CDATA[CHANGE ME]]></dynamic-content>
</dynamic-element>
</root>"

but after changing the text it is saved as below.

"<?xml version="1.0"?>
<root available-locales="en_US" default-locale="en_US">
<dynamic-element name="news" type="text" index-type="keyword" index="0">
<dynamic-content language-id="en_US">CHANGED VALUE</dynamic-content>
</dynamic-element>
</root>"

we can see here <![CDATA[]] is removed from the format.

MY code is as below :

com.liferay.portal.kernel.xml.Document document = null;
com.liferay.portal.kernel.xml.Node node = null;

content = rs.getString("content"); // get xml data from database which is having CDATA format.
document = SAXReaderUtil.read(content);
node = document.selectSingleNode("/root/dynamic-element[@name='"+ "news" + "']/dynamic-content");
node.getText() // it return = CHANGE ME
node.setText("CHANGED VALUE");
document = node.getDocument();
content = document.asXML();

content saved in database .
thumbnail
David H Nebinger, modified 6 Years ago.

RE: change content in XML database

Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
sunil kumar:
I want to change the XML data of content in journal article table.
i know liferay recommend to do this using liferay API , but i have to do this.


No, you don't have to do this. That is an excuse being made by someone that will not just say "no, we can't do this".

Tampering with the liferay database, especially in a case such as this, will lead to database corruption, environment instability and likely inoperability.

Anyone who says "I just have to modify the database directly" doesn't understand this core principle and should not be trusted to make any modifications to Liferay.

The Liferay database is not yours. I've said this time and time again. Forget it is there. Pretend your DB tool is broken. Never ever point it at the Liferay database and look at the contents. It is not yours to play with, it is not yours to look at, and it is not yours to modify.

Let's say, for example, that you somehow were able to figure this out. What about the related tables, are you going to update those too? Oh, you don't know that there are related tables? How are you prepared to deal with the subsequent Liferay failures? Oh, and web content is certainly also replicated in both the search index and local node caches, neither of which are updated when a table is modified directly. In fact, if you knew better, you would know that for this kind of scenario most of the time the docs come from the index, not the database, so when you change the DB you won't see a corresponding change in the UI.

There are reasons we say "don't look at or modify the database". It is not documented. Especially in columns that store XML or JSON, they are definitely not documented. It is subject to unannounced and unreported change. Columns with one name might have been deprecated (or even worse) repurposed without adjusting the name. The DB is just one cog in Liferay's machinery to quickly render and serve content, it is just the persistent store but is not the only runtime source of data.

If you don't use the Liferay API, you are abdicating your responsibilities as a Liferay admin and/or developer. It demonstrates that you are missing a basic understanding of one of the core principles of using and working with Liferay.

All of this may sound harsh, but it is meant to. If I've left you or someone else with the impression that what you're doing is wrong, that is totally the intent. I have been called in time and time again trying to "fix" things that someone modifying the DB directly has broken.








Come meet me at the 2017 LSNA!
Iñigo Boyano, modified 3 Years ago.

RE: change content in XML database

Junior Member Posts: 96 Join Date: 2/4/14 Recent Posts
Hi David, 

I understand that we CAN'T touch the DDBB directly but i have the following problem and i don´t know how to achieve it with API.

I create the post in this link, but in summary:

https://liferay.dev/forums/-/message_boards/message/119067086

I've changed by control panel a field type documents and media for field type Image (both fields with the same id)

The xml of the documents media field type is:

<dynamic-element name="Imagen" type="document_library" index-type="keyword" instance-id="drvp">
        <dynamic-content language-id="es_ES"><![CDATA[{"groupId":20142,"title":"title.jpg","type":"document","uuid":"f7b4ad48-216b-62be-15eb-2bc4e6d9eb2b"}]]>
/dynamic-content>
    </dynamic-element>

And the xml of a image type is:

<dynamic-element name="Imagen" type="image" index-type="text" instance-id="ojgq">
    <dynamic-content language-id="es_ES"><![CDATA[{"groupId":20142,"name":"title.jpg","alt":"","title":"title.jpg","type":"document","uuid":"5db1e897-5ef4-745b-45dc-57898d02ca57","fileEntryId":"38346","resourcePrimKey":"38371"}]]></dynamic-content>
</dynamic-element>

When i open the content (after the change of the structure), i see the new field (image) with the pre-loaded file that it was in the old field (documents and media) but in DDBB the xml of the content has the old version of the article with the dynamic element type =document_library. Until i don´t push the publish button, the content will not updated and if I use the journalArticleLocalServiceUtil.update(), as in DDBB the content is old, the update that liferay do is with the old content.

I need to do this submit function to republish the content by a groovy (because I have to change a lot of content associates that i change their structure field)

The solution i've made is to get the journal article xml content by journalArticleLocalService, edit the content classes of Document, Node..., like sunil did and then set the new xml content to the article and use journalArticleLocalService.update to set this new version of the journal.

In this point, I have the same problem, the new dynamic-content value has not CDATA start and it seems is not the correct solution.

Could you provide me another better solution?

Kind regards

Iñigo
thumbnail
Christoph Rabel, modified 6 Years ago.

RE: change content in XML database

Liferay Legend Posts: 1554 Join Date: 9/24/09 Recent Posts
Can you cast your node to an Element?
Element element = (Element) node;

Then you could call getContent() and use setContent to store CDATA objects.

But instead of fetching the content directly you should use JournalArticleLocalService to fetch the articles you want to change and call getContent/setContent to modify them. That way they are reindexed when you save them. Otherwise, if you do it directly in the database you need to reindex all articles.