Db4o Series – Collections Basics

Despues del DVP 2010 y la gorra xD tenia que dedicarle un post a db4o jeje.
Db4o puede manejar la persistencia de las listas de una manera natural, incluso dándonos incluso colecciones especiales con implementación para manejar persistencia y activación automática (Transparent Persistence y Transparent Activation). En este post voy a tratar de explicar las bases de como trabajar con colecciones y las operaciones comunes de base de datos con estas estructuras, no es el objetivo mostrar como optimizar el uso de colecciones o utilizar persistencia/activacion automática, sino comprender lo básico con la configuración necesaria para que funcione, es decir sin tunning.
Teniendo el siguiente modelo:

Donde la clase Project es la que tiene una lista de recursos, pudiendo ser del tipo Developer o ProjectLeader, vamos a manejar las operaciones en la coleccion de manera normal y vamos a dejar que db4o se encargue del resto 🙂
Las consideraciones que debemos tener para estas estructuras son:

  • Si no estamos utilizando Transparent Persistence debemos configurar la actualizacion en cascada (cascade on update) si vamos a modificar las propiedades de los objetos dentro de la colección (para este ejemplo vamos a hacerlo y tendremos que activar este feature).
configuration.common().objectClass(Project.class).
     cascadeOnUpdate(true);
  • No necesitamos código adicional para grabar los objetos agregados a las colecciones
  • Cuando se elimina un objeto de la lista y se graban los cambios, el objeto no es eliminado de la base de datos, simplemente la referencia es eliminada de la lista.
  • Cuando se elimina la referencia de un objeto de la base de datos y este estaba referenciado por una lista, se va la referencia a NULL ya que la lista nunca se entero que el objeto fue eliminado de la base de datos, tenemos que tener mucho cuidado para tener integridad en los objetos, una manera de solventar este tema es utilizando los callbacks y teniendo un diseño en ambas direcciones (el objeto de la colección tiene una referencia al objeto padre y se puede eliminar la referencia cuando se detecta que va a ser eliminado de la base de datos)

Con el modelo presentado anteriormente, queremos crear un proyecto con varios desarrolladores:

Project db4o = new Project("Db4Objects");
// Agregamos los recursos a la colección
db4o.getResources().add(new ProjectLeader("John Smith", 95000));
db4o.getResources().add(new Developer("Anne Lu", 35000));
db4o.getResources().add(new Developer("Marie Perez", 32000));
db4o.getResources().add(new Developer("Carl", 33000));
db4o.getResources().add(new Developer("Rodrigo", 35000));
container.store(db4o);

Para cualquiera que haya programado en Java le son natural las 6 primera lineas, solo la ultima linea corresponde al store de db4o que se encarga de guardar en la base de datos los objetos creados, todo el árbol de objetos desde el proyecto hasta los recursos, debido a la configuración de almacenamiento en cascada.

Así mismo podemos actualizar las listas añadiendo o removiendo objetos, o actualizando propiedades de los objetos en la colección.
Esto es lo que tiene la base de datos antes de hacer algún cambio:

Project: Db4Objects
John Smith – 95000.0
Anne Lu – 35000.0
Marie Perez – 32000.0
Carl – 33000.0
Rodrigo – 35000.0

Hacemos las actualizaciones

Query query = container.query();
query.constrain(Project.class);
//Consultamos el proyecto db4o para obtener el objeto y modificarlo
query.descend("name").constrain("Db4Objects");
ObjectSet result = query.execute();
Project db4o = (Project) result.next();
// Removemos un recurso del proyecto
db4o.getResources().remove(3);
// Actualizamos el salario de un recurso
Resource developer = db4o.getResources().get(1);
developer.setSalary(developer.getSalary() + 1000);
// Agregamos un nuevo desarrollador al proyecto
db4o.getResources().add(new Developer("Adam Pereiro", 50000));
//Guardamos los cambios
container.store(db4o);

Y el resultado es el siguiente:

Project: Db4Objects
John Smith – 95000.0
Anne Lu – 36000.0
Marie Perez – 32000.0
Rodrigo – 35000.0
Adam Pereiro – 50000.0

Nada complicado, ahora si queremos obtener el objeto principal a partir de un elemento de la colección, es decir si quisiéramos saber el proyecto de un recurso en especifico podemos utilizar Native Queries por ejemplo. Para el caso si tenemos varios proyectos y queremos obtener solo los que tienen recursos con un salario menor o igual a 30000.
Agregamos 2 proyectos adicionales

Project eclipseIDE = new Project("EclipseIDE");
eclipseIDE.getResources().add(new ProjectLeader("Carlos Field", 85000));
eclipseIDE.getResources().add(new Developer("Gian Lopez", 40000));
eclipseIDE.getResources().add(new Developer("Tania Mellas", 28000));
eclipseIDE.getResources().add(new Developer("Sara Parker", 37000));
eclipseIDE.getResources().add(new Developer("Neil Smith", 35000));

Project netBeans = new Project("Netbeans");
netBeans.getResources().add(new ProjectLeader("Karen Bowler", 23000));
netBeans.getResources().add(new Developer("Juan Perez", 18000));
container.store(netBeans);
container.store(eclipseIDE);

El query seria algo asi:

final double maxSalary = 30000;
List<Project> projects = container.query(new Predicate<Project>() {
 public boolean match(Project project) {
  for (Resource resource : project.getResources()) {
   if (resource.getSalary() <= maxSalary)
    return true;
   }
   return false;
  }
});

Lo cual nos daría como resultado:
…Projects with salary <= 30000…
Project: EclipseIDE
Project: Netbeans

Como podemos ver no tenemos que preocuparnos por nada mas que lo que en este caso Java provee con el api de Collections y tan solo con un store lo hacemos persistir en la base de datos! En un post posterior mejorare el modelo para que tenga Activación y Persistencia Automática y el manejo del borrado de referencias.

Saludos,
gish@c

Descargas (Proyecto Eclipse para Db4o7.12)

DVP 2010

Hoy quería agradecer a la gente de db4o por el reconocimiento de Db4o Most Valued Professional 2010 (DVP). Es muy interesante contribuir a ésta comunidad y aprender siempre algo nuevo del paradigma ODBMS, sobre todo si es un producto tan bueno como db4o (si aún no lo han revisado se los recomiendo al 100%).
Fue muy gratificante contribuir en alguno que otro feature del Object Manager (Java Version) (No nos fue tan mal, las 2 versiones liberadas suman 6000 descargas!!!), lamentablemente no da más el tiempo para seguir aportando de esa manera, y por otro lado desde hace bastante tiempo el Object Manager Enterprise es free, así que hay un buen producto de exploración de objetos; aunque sinceramente no estaría mal si algún miembro de la comunidad inicia un proyecto para crear otro explorer, en lo personal por el tipo de aplicación creo que encajaría perfecto con Netbeans Platform como base xD

En fin, muchas gracias por el reconocimiento!!! A partir de hoy agrego el badge de DVP 2010 al blog junto a los de los años anteriores 😀

Saludos,
gish@c