1

I´ve set up a project to test marshalling for another project. Marshalling is working. I get the correct xml file, but unmarshalling is NOT working. I only get the Relation name (String). The attributes and functional dependencies are missing.

EDIT: Here is the source: Sourcecode

Please take a look at the classes:

Main:

public class Main {

public static void main(String[] args){

    Relation db = new Relation();

    Attribute a1 = new Attribute("Attribute 1", true, false);
    Attribute a2 = new Attribute("Attribute 2", false, false);
    Attribute a3 = new Attribute("Attribute 3", false, true);

    db.addAttribute(a1);
    db.addAttribute(a2);
    db.addAttribute(a3);

    ArrayList<String> src = new ArrayList<String>();
    src.add("Attribute 1");

    ArrayList<String> dest = new ArrayList<>();
    dest.add("Attribute 2,Attribute 3");

    FDs f1 = new FDs(src, dest);

    db.addFd(f1);

    exportToXml saver = new exportToXml();
    try {
        saver.SaveDbNow(db);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //Export again to test output
    Relation db2 = new Relation();

    importFromXml reader = new importFromXml();
    try {
        reader.ReadDbNow(db2);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        saver.SaveDbNow2(db2);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

Relation:

@XmlRootElement(name = "Relation")
public class Relation {
@XmlElement(name = "RelName")
String name;

@XmlElement(name = "Attribute")
private ArrayList<Attribute> attrList;
@XmlElement(name = "FD")
private ArrayList<FDs> fdsList;

public Relation() {
    this.attrList = new ArrayList<>();
    this.fdsList = new ArrayList<>();
    this.name = "Testname";
}

public Relation(String name, ArrayList<Attribute> attrList, ArrayList<FDs> fdsList)   {
    super();
    this.attrList = attrList;
    this.fdsList = fdsList;
}

@XmlTransient
public ArrayList<Attribute> getAttrList() {
    return attrList;
}

public void setAttrList(ArrayList<Attribute> attrList) {
    this.attrList = attrList;
}

@XmlTransient
public ArrayList<FDs> getFdsList() {
    return fdsList;
}

public void setFdsList(ArrayList<FDs> fdsList) {
    this.fdsList = fdsList;
}

public void addAttribute(Attribute a) {
    this.attrList.add(a);
}

public void addFd(FDs fd) {
    this.fdsList.add(fd);
}

}

Attribute:

public class Attribute {
@XmlElement( name = "Attributename")
private String name;
@XmlElement( name = "isPK")
private boolean isPK;
@XmlElement( name = "isFK")
private boolean isFK;

public Attribute(){

}


public Attribute(String name, boolean isPK, boolean isFK) {
    super();
    this.name = name;
    this.isPK = isPK;
    this.isFK = isFK;
}

@XmlTransient
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
@XmlTransient
public boolean isPK() {
    return isPK;
}

public void setPK(boolean isPK) {
    this.isPK = isPK;
}

@XmlTransient
public boolean isFK() {
    return isFK;
}
public void setFK(boolean isFK) {
    this.isFK = isFK;
}   
}

FD:

public class FDs {
@XmlElement( name = "Source")
private ArrayList<String> src;
@XmlElement( name = "Destination")
private ArrayList<String> dest;

public FDs(){

}

public FDs(ArrayList<String> src, ArrayList<String> dest) {
    super();
    this.src = src;
    this.dest = dest;
}

@XmlTransient
public ArrayList<String> getSrc() {
    return src;
}
public void setSrc(ArrayList<String> src) {
    this.src = src;
}

@XmlTransient
public ArrayList<String> getDest() {
    return dest;
}
public void setDest(ArrayList<String> dest) {
    this.dest = dest;
}
}

Export:

public class exportToXml {

public void SaveDbNow(Object saveMe) throws Exception {
    JAXB.marshal(saveMe, new File("test.xml"));
}

public void SaveDbNow2(Object saveMe) throws Exception {
    JAXB.marshal(saveMe, new File("test2.xml"));
}
}

Import:

public class importFromXml {

public void ReadDbNow(Object readMe) throws Exception {
    readMe = JAXB.unmarshal(new FileInputStream("test.xml"), Relation.class);
}
}

Thanks in advance!

EDIT: Output1:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relation>
<RelName>Testname</RelName>
<Attribute>
    <Attributename>Attribute 1</Attributename>
    <isPK>true</isPK>
    <isFK>false</isFK>
</Attribute>
<Attribute>
    <Attributename>Attribute 2</Attributename>
    <isPK>false</isPK>
    <isFK>false</isFK>
</Attribute>
<Attribute>
    <Attributename>Attribute 3</Attributename>
    <isPK>false</isPK>
    <isFK>true</isFK>
</Attribute>
<FD>
    <Source>Attribute 1</Source>
    <Destination>Attribute 2,Attribute 3</Destination>
</FD>

Output2:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relation>
<RelName>Testname</RelName>
</Relation>
Andreas Freitag
  • 357
  • 1
  • 7
  • 20

2 Answers2

1

Explanation for Current Behaviour

In the Main class you instantiate a new instance of Relation the constructor populates the name property to "Testname". Nothing else is ever populated on in the instance of Relation this is why you are seeing the XML output that you are.

    // Export again to test output
    Relation db2 = new Relation();

    importFromXml reader = new importFromXml();
    try {
        reader.ReadDbNow(db2);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        saver.SaveDbNow2(db2);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Potential Solution

Change the ReadDbNow method on the importFromXml class to return the instance of Relation that it unmarshalled.

import java.io.FileInputStream;
import javax.xml.bind.JAXB;

public class importFromXml {

    public Relation ReadDbNow() throws Exception {
        return JAXB
                .unmarshal(new FileInputStream("test.xml"), Relation.class);
    }
}

In the Main class change your code to do the following:

    // Export again to test output
    Relation db2 = null;

    importFromXml reader = new importFromXml();
    try {
        db2 = reader.ReadDbNow();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        saver.SaveDbNow2(db2);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
bdoughan
  • 147,609
  • 23
  • 300
  • 400
0

You need to annotate your classes with @XmlRootElement . Eg. Attribute does not have the annotation

fmucar
  • 14,361
  • 2
  • 45
  • 50