8

Right now I have java program whose classes are currently POJOs and stored in volatile memory. These need to be persisted. As I understand it two popular choices are JDO and the Java Persistence API. For someone who know little about SQL, Torque, etc, which is the easiest way to add persistence to my program's data?

Dmitri Chubarov
  • 13,673
  • 4
  • 30
  • 64
James
  • 5,023
  • 10
  • 46
  • 76

6 Answers6

8

The traditional way to serialise to the filesystem is to use Java Serialisation. However you need to implement Serializable everywhere.

A simpler solution is to serialise to XML (and then dump to the filesystem) using XStream. You don't need to implement any interfaces, and most everything serialises and deserialises without further intervention. You can further customise the serialisation if required. The only problem I've ever had is serialising an inner class without intentionally serialising the containing outer class (this is due to the implicit this reference)

Amine Zaine
  • 136
  • 18
Brian Agnew
  • 254,044
  • 36
  • 316
  • 423
6

Serialize the objects to the file system if you don't know SQL or relational databases.

You'll have to learn JDBC to use JDO, JPA, Hibernate, or anything else. Unless your POJOs are terribly complex I'd recommend starting there and working your way up.

Make sure you learn about normalization and proper design of indexes.

duffymo
  • 293,097
  • 41
  • 348
  • 541
  • To use JDO, JPA or Hibernate you clearly don't need to know JDBC since that is the point of those APIs. They use JDBC under the covers when persisting to RDBMS, so that complexity is hidden from you – DataNucleus Dec 25 '09 at 19:07
  • 3
    I disagree - it's not advisable to use them without knowing JDBC. The complexity is hidden, but it's a leaky abstraction. – duffymo Dec 25 '09 at 20:26
  • 1
    Not a leaky abstraction with JDO, though certainly JPA and Hibernate are strongly tied to JDBC. Depends on which API the questioner decides to go – DataNucleus Dec 26 '09 at 09:20
  • 1
    I don't know JDO well enough to assess it's abstraction-tightness, but I wouldn't recommend that anyone do persistence with a relational database without knowing anything about them. – duffymo Dec 26 '09 at 13:24
5

The easiest way I came across as yet is db4o:

ObjectContainer db = Db4o.openFile(location);
db.store(myObject);
List<MyObject> myObjects = db.query(MyObject.class);

Plus there are really nice ways to query in other ways.

Fabian Steeg
  • 42,835
  • 6
  • 79
  • 111
  • Sadly: In October 2014, Actian declined to continue to actively pursue and promote the commercial db4o product offering for new customers. http://supportservices.actian.com/versant/default.html – Jonathan Apr 20 '17 at 07:31
5

If serialization is an option, consider using a prevalence API like prevalayer or Space4J (more recent). About object prevalence:

Prevalence is a concept started by Klaus Wuestefeld on how to store data in a real object oriented way, using only memory snapshots, transaction logs and serialization.

Check this article to learn more on this topic (more on Google).

Pascal Thivent
  • 535,937
  • 127
  • 1,027
  • 1,106
2

Sounds like you may want to persist to a DB. However, to avoid the complexities of a DB one simple solution for persisting POJOs to the file system is to serialize them to an XML document. The Java 1.6 API includes the JAXB framework found in the javax.xml.bind package. To use JAXB you essentially annotation your POJO and create marshal and unmarshal methods like so:

@XmlRootElement(name="Foo")
public class Foo {

   @XmlElement(name="Bar")
   public int mBar;

   public static void marshal(Foo foo, OutputStream out) IOException {      
      try {
         JAXBContext jc = JAXBContext.newInstance(Foo.class);
         Marshaller marshaller = jc.createMarshaller();
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
         marshaller.marshal(qaConfig, out);
      }
      catch (JAXBException ex) {
         throw new IOException(ex);
      }
      finally {
         out.close();
      }
   }

   public static Foo unmarshal(InputStream in) throws IOException {

      try {
         JAXBContext jc = JAXBContext.newInstance(Foo.class);
         Unmarshaller unmarshaller = jc.createUnmarshaller();

         return (Foo)unmarshaller.unmarshal(in);
      }
      catch (JAXBException ex) {
         throw new IOException(ex);
      }
      finally {
         in.close();
      }
   }
}

Lets say you persist an instance of Foo where mBar is 42 then this solution would produce an XML file like so:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Foo>
   <Bar>42</Bar>
</Foo>
jenglert
  • 1,379
  • 12
  • 23
  • 1
    DataNucleus hides all of that marshalling and unmarshalling from the user and they simply add JDO or JPA annotations to the classes they want to persist. Less code. Less to handle – DataNucleus Dec 25 '09 at 19:08
2

DataNucleus is the easiest way since it provides JDO and JPA APIs for persistence to pretty much any type of datastore you would ever want. Why write all of that JAXB code in one of the other replies when DataNucleus does it for you? All backed by Java standards, and open source.

Disclosure: the author of this answer is associated with the DataNucleus project.

Max von Hippel
  • 2,468
  • 2
  • 28
  • 41
DataNucleus
  • 15,199
  • 3
  • 30
  • 37