Details
-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
17.1.0
-
None
-
Unknown
-
Description
When filtering a document with several revisions with unordered versions, some versions overwrite previous ones because they end up being assigned existing versions.
This can be reproduced with the buggyhistory.xml attachment and the Filter Stream Converters application. This file is to be given as the source of the input+xml filter, and the xwiki+instance filter is to be used.
The input is clearly buggy, but the filter streams should probably not overwrite revisions silently. I guess an acceptable outcome would be to throw a filter exception complaining about the wrong version order.
Investigation
That's because the save archive mechanism forces versions to be increasing. If the requested version is not higher than the previous one, a new version is actually created, incrementing the previous one.
Also, when saving a document, if its version already exists, a new one is not created, the existing one is updated.
Thus, when versions are not ordered, some versions will overwrite existing ones
When that happens, there is this stack trace (on a XWiki 17.0.0 instance):
createNextVersion:117, XWikiDocumentArchive (com.xpn.xwiki.doc)
updateArchive:294, XWikiDocumentArchive (com.xpn.xwiki.doc)
updateXWikiDocArchive:315, XWikiHibernateVersioningStore (com.xpn.xwiki.store)
saveXWikiDoc:664, XWikiHibernateStore (com.xpn.xwiki.store)
saveXWikiDoc:275, XWikiCacheStore (com.xpn.xwiki.store)
saveXWikiDoc:235, XWikiCacheStore (com.xpn.xwiki.store)
saveDocument:2110, XWiki (com.xpn.xwiki)
maybeSaveDocument:252, DocumentInstanceOutputFilterStream (com.xpn.xwiki.internal.filter.output)
endWikiDocumentRevision:164, DocumentInstanceOutputFilterStream (com.xpn.xwiki.internal.filter.output)
invoke:-1, GeneratedMethodAccessor138 (jdk.internal.reflect)
invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)
invoke:569, Method (java.lang.reflect)
invoke:90, FilterProxy (org.xwiki.filter.internal)
invoke:75, CompositeFilter (org.xwiki.filter.internal)
endWikiDocumentRevision:-1, $Proxy410 (jdk.proxy96)
invoke:-1, GeneratedMethodAccessor138 (jdk.internal.reflect)
invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)
invoke:569, Method (java.lang.reflect)
invoke:90, FilterProxy (org.xwiki.filter.internal)
invoke:75, CompositeFilter (org.xwiki.filter.internal)
endWikiDocumentRevision:-1, $Proxy411 (jdk.proxy96)
invoke:-1, GeneratedMethodAccessor138 (jdk.internal.reflect)
invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)
invoke:569, Method (java.lang.reflect)
fireEvent:228, DefaultXMLParser$Block (org.xwiki.filter.xml.internal.parser)
fireEndEvent:168, DefaultXMLParser$Block (org.xwiki.filter.xml.internal.parser)
endElement:440, DefaultXMLParser (org.xwiki.filter.xml.internal.parser)
endElement:558, XMLFilterImpl (org.xml.sax.helpers)
handleEndElement:211, SAXEventWriter (org.xwiki.xml.stax)
convertEvent:117, SAXEventWriter (org.xwiki.xml.stax)
sendEvent:91, SAXEventWriter (org.xwiki.xml.stax)
add:519, BaseXMLEventWriter (javanet.staxutils)
add:527, BaseXMLEventWriter (javanet.staxutils)
copy:383, XMLStreamUtils (javanet.staxutils)
read:62, AbstractXMLInputFilterStream (org.xwiki.filter.xml.internal.input)
runInternal:97, FilterStreamConverterJob (org.xwiki.filter.internal.job)
runInContext:246, AbstractJob (org.xwiki.job)
run:223, AbstractJob (org.xwiki.job)
run:75, ScriptFilterStreamConverterJob (org.xwiki.filter.script.internal)
runWorker:1136, ThreadPoolExecutor (java.util.concurrent)
run:635, ThreadPoolExecutor$Worker (java.util.concurrent)
run:840, Thread (java.lang)
Here's an excerpt of updateArchive: (https://github.com/xwiki/xwiki-platform/blob/33b296d403901034fdc09f498dc6f4a750bda4d9/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/doc/XWikiDocumentArchive.java#L288-L296):
public void updateArchive(XWikiDocument doc, String author, Date date, String comment, Version version, XWikiContext context) throws XWikiException { Version oldLatestVer = getLatestVersion(); Version newVer = version; if (newVer == null || oldLatestVer != null && newVer.compareVersions(oldLatestVer) <= 0) { newVer = createNextVersion(oldLatestVer, doc.isMinorEdit()); }
This if causes the decision to go with a new version instead of the requested one. Link to [`createNextVersion`](https://github.com/xwiki/xwiki-platform/blob/33b296d403901034fdc09f498dc6f4a750bda4d9/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/doc/XWikiDocumentArchive.java#L114)
in saveXWikiDoc, line 664 (https://github.com/xwiki/xwiki-platform/blob/33b296d403901034fdc09f498dc6f4a750bda4d9/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java#L662-L665):
if (!containsVersion(doc, doc.getRCSVersion(), context)) { context.getWiki().getVersioningStore().updateXWikiDocArchive(doc, false, context); }
This is the decision to update the doc archive only if the doc version is not already found.
Attachments
Issue Links
- relates to
-
CONFLUENCE-415 Revision order is sometimes wrong
-
- Closed
-
-
CONFLUENCE-416 Preferably order page revisions by version
-
- Closed
-