UPDATE : Merci funql/Kim. Je comprends votre point de vue. Si vous me permettez une question complémentaire, existe-t-il un moyen de réaliser la persistance des objets (comme suggéré par Funql pour Mongo) à l'aide de Couch ? D'après ce que j'ai compris avant de commencer ce projet, c'est l'un des avantages des bases de données NoSQL - vous n'avez pas besoin de vous soucier des couches DAO, vous pouvez pratiquement déverser un objet dans un document et l'extraire au besoin, sans problème, laissant la définition du schéma être entièrement impliquée par la définition de votre classe, et je ne vois pas de raison fondamentale pour laquelle cela fonctionnerait dans MongoDB mais pas dans CouchDB ?
J'utilise CouchDB pour la première fois dans une application d'entreprise et j'ai l'impression qu'il me manque quelque chose de fondamental dans la mentalité NoSQL.
Supposons que vous ayez les classes Java suivantes :
public class Customer { ... }
public abstract class Product { ... } // could just as well be an interface
public class ProductA extends Product { ... };
public class ProductB extends Product { ... };
public class Sale {
private String transactionId;
private Customer customer;
private List<Product> items;
// ...
}
Lorsque je stocke une vente dans une base de données Couch (ou toute autre base de données de stockage de documents), je me retrouve avec un seul document contenant l'intégralité de la vente, ce qui est ce que je veux. Cependant, je rencontre un problème dès que je commence à essayer de stocker/récupérer des classes abstraites ou des classes qui implémentent une interface. L'enregistrement de ma vente ressemble généralement à quelque chose comme ceci (simplifié) :
{
"transactionId": "12345",
"customer": { "name": "Joe Soap" },
"items": [
{
"name": "Coke",
"price": 12.99,
"qty": 1
},
{
"name": "Minced meat",
"weight": 1.23,
"price": 49.99
}
]
}
Maintenant, la récupération de ces données est simple dans le cas du client - je peux utiliser un sérialiseur/désérialiseur personnalisé et utiliser la réflexion pour dire que Sale.customer
est une instance de Customer
, instanciez une instance et définissez ses champs à partir des données JSON.
Cependant, cela devient beaucoup plus délicat avec le items
car je n'ai aucune idée de la sous-classe de Product
à instancier pour chaque élément de la liste (et je ne peux pas initialiser une instance d'une classe abstraite ou d'une interface).
J'ai essayé de contourner ce problème en stockant le nom complet de la classe avec les données (par exemple chaque Product
L'enregistrement contiendrait un @class
pour indiquer quel type d'objet a été sérialisé, et donc quel type doit être initialisé lors de la désérialisation), mais cela signifie que je me crée un problème si jamais, par exemple, je déplace cette classe dans un autre paquetage (comme le champ @class
sera alors invalide). Bien que cela puisse être atténué avec la migration scripts (ou d'autres approches), j'ai l'impression de passer à côté d'un point fondamental et de le contourner.
Quelqu'un peut me dire ce que je fais de mal ? Existe-t-il une approche plus élégante qui me permettrait de ne pas avoir à manipuler autant le code de sérialisation, puisque je crois comprendre que les bases de données NoSQL sont censées réduire le temps que les développeurs doivent passer à écrire du code de persistance ?
Pour ce que ça vaut, j'ai essayé d'utiliser Ektorp et LightCouch, et j'ai eu des problèmes similaires avec les deux.