简体   繁体   中英

JAXB unmarshalling not working

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>

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();
    }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM