views:

468

answers:

6

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?

+5  A: 

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
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
I disagree - it's not advisable to use them without knowing JDBC. The complexity is hidden, but it's a leaky abstraction.
duffymo
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
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
+2  A: 

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
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
+2  A: 

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)

Brian Agnew
+2  A: 

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
+2  A: 

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
A: 

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

DataNucleus