Search code examples
apache-sparkjaxbmarklogicapache-spark-mllib

Marshalling is not working with JAXBHandle in MarkLogic


I want to store following object in to MarkLogic.

@XmlRootElement(name = "trainModel")
@XmlAccessorType(XmlAccessType.FIELD)
public class TrainedModel implements Serializable {

    private static final long serialVersionUID = 1L;

    private String modelName;
    private CrossValidatorModel crossValidatorModel;

    public String getModelName() {
        return modelName;
    }

    public void setModelName(String modelName) {
        this.modelName = modelName;
    }

    public CrossValidatorModel getCrossValidatorModel() {
        return crossValidatorModel;
    }

    public void setCrossValidatorModel(CrossValidatorModel crossValidatorModel) {
        this.crossValidatorModel = crossValidatorModel;
    }

    @Override
    public String toString() {
        return "TrainedModel [modelName=" + modelName + ", crossValidatorModel=" + crossValidatorModel + "]";
    }
}

I am using JAXBHandle to complete my requirement but while storing TrainedModel object in to MarkLogic, CrossValidatorModel is getting empty.

CrossValidatorModel is external object provided by org.apache.spark.ml.tuning.CrossValidatorModel.

I tried below code,

    CrossValidatorModel crossValidatorModel = createDataFrame(null);
    TrainedModel trainedModel = new TrainedModel();
    trainedModel.setModelName("sample");
    trainedModel.setCrossValidatorModel(crossValidatorModel);
    
    JAXBContext context = JAXBContext.newInstance(TrainedModel.class);  
    JAXBHandle<TrainedModel> jaxbHandle = new JAXBHandle<TrainedModel>(context);
    jaxbHandle.set(trainedModel);
    
    GenericDocumentManager docMgr = client.newDocumentManager();
    docMgr.writeAs("/shivling.xml", null, jaxbHandle);

this is the xml I am getting as result,

<?xml  version="1.0" encoding="UTF-8"?>
<trainModel>
    <modelName>sample</modelName>
    <crossValidatorModel>
    </crossValidatorModel>
</trainModel>

crossValidatorModel is empty here, Please help me to resolve this issue.


Solution

  • NULL (in your code) with repercussion in XML: Your result suggests semantic issue in your code.

    JAXB framework can be delivered through proper MarkLogic Document Manager or old POJO way:

    A simple MarkLogic JAXB annotation (You would use DMSDK in bulk read | write transactions):

    Code Snippet:

            XMLDocumentManager docMgr = marklogic.newXMLDocumentManager();
    
            TrainedModel trainedModel = new TrainedModel();
                
            trainedModel.setModelName("History and Psychology");
            trainedModel.setCrossValidatorModel("Biology");
    
            String docId = "/train-model.xml";
    
            docMgr.writeAs(docId, trainedModel);
    

    Result: enter image description here

    Subpar IO method:

        TrainedModel trainedModel = new TrainedModel();
                
            trainedModel.setModelName("History and Current Affairs");
            trainedModel.setCrossValidatorModel("Psychology");
            
            // initialize JAXB 
            JAXBContext context = JAXBContext.newInstance(TrainedModel.class);
            
            // POJO Handle
            JAXBHandle<TrainedModel> writeHandle = new JAXBHandle<TrainedModel>(context);
            
            // Marshalling
            Marshaller jaxMar = context.createMarshaller();
                
            String docId = "/train-model.xml";
    
            // IsMarshalled
            jaxMar.marshal(trainedModel, System.out);
    
            // set Handle
            writeHandle.set(trainedModel);
    
           // write POJO to MarkLogic
            docMgr.write(docId, writeHandle);