Simple medical collection/database about patients visits I am writing a system for doctors who are regularly visited by patients. The doctor adds each patient's visit to collection/database. The class can save data to an .xml file and restore it. Can you give your feedback about this code? 

// https://github.com/veitsi/jcrf-noweb
import java.util.ArrayList;
import java.util.Date;
import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Jcrf {
    @XmlElement
    Jcrf jcrf;
    @XmlElement
    ArrayList&lt;Visit&gt; vst = new ArrayList&lt;Visit&gt;();

    public Jcrf() {
        super();
    }

    public static void main(String[] args) {
        Jcrf jcrf = new Jcrf();
         jcrf.addTestData();

        System.out.println(jcrf.vst);

        jcrf.toXml();
        jcrf.fromXml();

        System.out.println(jcrf.vst);
    }

    public void toXml() {
        try {
            File file = new File("jcrf.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance(Jcrf.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); // output
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(this, file);
            jaxbMarshaller.marshal(this, System.out);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    public void fromXml() {
        try {
            File file = new File("jcrf.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance(Jcrf.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            jcrf = (Jcrf) jaxbUnmarshaller.unmarshal(file);
            vst = jcrf.vst;
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    public void addTestData() {
        vst.add(new Visit(1, 1, 366));
        vst.add(new Visit(1, 2, 365));
        vst.add(new Visit(2, 1, 364));
    }
}

class Visit {
    @XmlElement
    int ptn;
    @XmlElement
    int nmr;
    @XmlElement
    static final Date dt = new Date();
    @XmlElement
    int ttr;

    public Visit() {
    }

    public Visit(int ptn, int nmr, int ttr) {
        super();
        if (ttr &lt; 300 || ttr &gt; 420)
            throw new IllegalArgumentException("bad temperature");
        this.ptn = ptn;
        this.nmr = nmr;
        this.ttr = ttr;
    }

    @Override
    public String toString() {
        return "Visit [ptn=" + ptn + ", nmr=" + nmr + ", ttr=" + ttr + ", dt="
                + dt + "]";
    }

}
File-systems normally make poor databases because you lose the concept of 'atomicity'... let's take a worst-case example:


public void toXml() {
    try {
        File file = new File("jcrf.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(Jcrf.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); // output
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        jaxbMarshaller.marshal(this, file);
        jaxbMarshaller.marshal(this, System.out);
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}



What happens if there is an IOException part-way through the jaxbMarshaller.marshal(this, file); ? You end up overwriting the old copy, and losing the new one. Your data is gone.

A more traditional way to prevent this sort of loss is to write the output to a new file, and then do an atomic 'move' operation:

public void toXml() {
    try {
        File file = new File("jcrf.xml.tmp");
        JAXBContext jaxbContext = JAXBContext.newInstance(Jcrf.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); // output
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        jaxbMarshaller.marshal(this, file);
        jaxbMarshaller.marshal(this, System.out);

        // move tmp file to complete output file.
        Path tmp = file.toPath();
        Path target = Paths.get("jcrf.xml");
        Files.move(tmp, target, CopyOption.REPLACE_EXISTING, CopyOption.ATOMIC_MOVE);

    } catch (JAXBException e) {
        e.printStackTrace();
    }
}


Note the use of the atomic Files.move(...)` command.

One day, when your file-system is full, and you run out of space... you will appreciate that change.