Exception : “Missing class indicator field from database row [UnmarshalRecordImpl()].” when unmarshalling XML using EclipseLink JAXB (MOXy)

99封情书 提交于 2019-12-21 06:04:48

问题


Is it any way to unmarshalling with @XmlDescriminatorNode/@XmlDescrimintatorValue annotations next XML, or any workaround:

<assets>
    <asset type="full">
        <data_file role="source">
            <locale name="ru-RU"/>
        </data_file>
        <data_file role="extension">
            <locale name="ru-RU"/>
        </data_file>
        <data_file>
            <locale name="ru-RU"/>
        </data_file>
    </asset>
</assets>

My mapping classes:

@XmlRootElement(name="data_file")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlDiscriminatorNode("@role")
public abstract class BaseDataFile implements Serializable {

    @XmlPath("@role")
    @XmlAttribute(name = "role")
    private String role;

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}
@XmlRootElement(name="data_file")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlDiscriminatorValue("source")
public class SourceDataFile extends BaseDataFile {

}
@XmlRootElement(name="data_file")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlDiscriminatorValue("source")
public class SourceDataFile extends BaseDataFile {

}
@XmlRootElement(name="data_file")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlDiscriminatorValue("extension")
public class SourceDataFile extends BaseDataFile {

}
@XmlRootElement(name="asset")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlDiscriminatorNode("@type")
public abstract class BaseAsset implements Serializable {

    @XmlPath("@type")
    @XmlAttribute(name = "type")
    private String type;

    @XmlPath("data_file")
    private List<BaseDataFile> dataFiles;

    public List<BaseDataFile> getDataFiles() {
        return dataFiles;
    }

    public void setDataFiles(List<BaseDataFile> dataFiles) {
        this.dataFiles = dataFiles;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

The error occures if XML containes element as below, without "type" attribute:

<data_file>
  <locale name="ru-RU"/>
</data_file>

Thanks in advance


回答1:


The following should help:

JAVA MODEL

Super Class (BaseDataFile)

Below is a simplified version of your BaseDataFile class. Since you have mapped the XML attribute role as the inheritance indicator you do not need to also map it to a property in your object model.

import java.io.Serializable;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({SourceDataFile.class, ExtensionDataFile.class})
@XmlDiscriminatorNode("@role")
public abstract class BaseDataFile implements Serializable {

}

If you really want to map the role XML attribute to a property in your object model you should use MOXy's @XmlReadOnly property to prevent it being marshalled to the XML document (it will already be wriiten as the inheritance indicator).

import java.io.Serializable;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;
import org.eclipse.persistence.oxm.annotations.XmlReadOnly;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({SourceDataFile.class, ExtensionDataFile.class})
@XmlDiscriminatorNode("@role")
public abstract class BaseDataFile implements Serializable {

    @XmlAttribute
    @XmlReadOnly
    String role;

}

Subclass (SourceDataFile)

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlDiscriminatorValue("source")
public class SourceDataFile extends BaseDataFile {

}

MISSING INHERITANCE INDICATOR

Base Class is not Abstract

If your base class (BaseDataFile) had not been abstract then if the inheritance indicator was missing an instance of the base class would have been created.

Base Class is Abstract

Since your base class is abstract MOXy complained about the missing inheritance indicator value:

Exception in thread "main" Local Exception Stack: 
Exception [EclipseLink-44] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class indicator field from database row [UnmarshalRecordImpl()].
Descriptor: XMLDescriptor(forum15597322.BaseDataFile --> [])
    at org.eclipse.persistence.exceptions.DescriptorException.missingClassIndicatorField(DescriptorException.java:957)
    at org.eclipse.persistence.internal.oxm.XMLRelationshipMappingNodeValue.processChild(XMLRelationshipMappingNodeValue.java:83)
    at org.eclipse.persistence.internal.oxm.XMLCompositeCollectionMappingNodeValue.startElement(XMLCompositeCollectionMappingNodeValue.java:184)
    at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.startElement(UnmarshalRecordImpl.java:834)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:506)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:376)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2715)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:488)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568)
    at org.eclipse.persistence.internal.oxm.record.XMLReader.parse(XMLReader.java:221)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:895)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:388)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:366)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:323)
    at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:367)
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:123)
    at forum15597322.Demo.main(Demo.java:23)

IGNORING THE ERROR

JAXB (JSR-222) implementations including MOXy report exceptions encountered during marshalling/unmarshaling to a ValidationEventHandler the default one will error out when a missing inheritance indicator value is encountered. Below is an example of setting a custom ValidationEventHandler that says never error out by returning true from the handleEvent method.

    Unmarshaller unmarshaller = jc.createUnmarshaller();
    unmarshaller.setEventHandler(new ValidationEventHandler() {
        @Override
        public boolean handleEvent(ValidationEvent event) {
            return true;
        }

    });

While putting this answer together I found the following MOXy bug which as a result of doing the above will put an invalid text value as an item in the collection. The fix is targeted against EclipseLink 2.5.1.

  • http://bugs.eclipse.org/404269

Once that fix goes in the invalid entry will just be ignored. Is this the behaviour you are looking for?


FOR MORE INFORMATION

  • http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-moxy-extension.html
  • http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html
  • http://blog.bdoughan.com/2010/07/xpath-based-mapping.html


来源:https://stackoverflow.com/questions/15597322/exception-missing-class-indicator-field-from-database-row-unmarshalrecordimp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!