views:

43

answers:

4

Suppose you have a huge app with a data access layer bound to SQL You want to provide other non-sql DAL, for instance a GoogleAppEngine instance or XML-based backup. How would you approach this migration to a different storage paradigm but with limited flexibility, since it is legacy.

I might be missing info here, but One solution I have in mind is to first rewrite the current legacy DAL into a standard API base, for instance JDO; from there, interfacing with any storage would be a matter of time based on the technology-specific learning curve.

AND OR NAND?

A: 

A lot depends on the specific details, but from what you describe I would probably start by building a Data Access Layer with DAO's that explicitly define an interface and an implementation to the current store.

Once that is up and running you can start creating an implementation of the interfaces to your new storage and migrate step by step.

rsp
A: 

In theory, as you also mentioned, you just need to use some standard interface like JPA, and change the implementation or the storage behind it. Unfortunately, in practice this doesn't work so smoothly. It can be done, but you're surely gonna spend some time on issues you just didn't expect.

I would start by stabilizing the service interfaces, and migrate them feature by feature. Start with the easiest one, something that is small enough and separated from the other parts of the system.

However, as a first step, it's not a bad idea to rewrite your code to use some standard interface. JDO is known to handle non-relational databases somewhat better, so you might benefit from choosing it.

As for Google App Engine, most probably you will need to change your data model entirely, if you have already designed it with an RDBMS in mind. Just to mention a few constraints, there is no JOIN, and you also cannot use OR in your queries. So I suggest you to experiment with it before you jump into some huge migration project.

candiru
that's the issue at stake indeed.The good news is that my webapp is layered so that the DAOs can be changed entirely internally without affecting the system, provided that their interfaces (I/O) remain the same. For instance, as far as CRUD ops are concerned, the change was smooth. But as you guessed, now we are getting stuck with joins and the like, features which are only available on RDBMS...Aren't there some JDBC-POJO wrappers, or can you do such things as JOIN with JDO?
k.honsali
Since the storage engine behind Google App Engine (BigTable) is basically a distributed key-value storage, it is and will not be possible to do this. You have to come up with some workaround, but this depends on how your application works.
candiru
A: 

DataNucleus, as used by GAE/J for BigTable, also supports persistence to XML ... using JDO. Consequently it would be trivial to support persistence to that too. You have limited joining capabilities in GAE/J ... not a limit of JDO, just of how they have implemented such a thing in the GAE/J plugin.

--Andy (DataNucleus)

DataNucleus
A: 

Indeed, GAE/J does have a limited JDO api (0) ; their use of the JDO naming is misleading ... :(

On the other side, as you suggested, JDO does support Joins, as annotations (1) and/or as metadata(2); which can be retrieved afterwards using a JDOQL query.

Please correct me if I am wrong, but JDO\JDOQL feels less powerful than an SQL query. The power of SQL is the capability to join on the fly a multitude of related tables. I still cannot see how can I support such a query, like this simple example from my webapp

(human) schema: a product line has many catalogs, which have many products, any invoice has any of those products

SELECT a.id, a.name, b.id, b.name, c.id, c.name  from products a
left join catalog b on b.id = a.fk_catalog_id
left join productline c on c.id = b.fk_productline_id
where a.id in (select distinct product_id from invoice_product where invoice_id = <PARAM> )

links:

theweb@(0); code.google.com/intl/fr-FR/appengine/docs/java/datastore/usingjdo.html#Unsupported_Features_of_JDO

theweb@(1); www.datanucleus.org/products/accessplatform/jdo/annotations.html#Joins

theweb@(2); www.datanucleus.org/products/accessplatform/jdo/orm/one_to_many_list.html#join_uni

k.honsali
You don't do an SQL query in any other datastore than RDBMS, obviously. All object-oriented queries are typically achievable in JDOQL, maybe using variables, or maybe not depending on the classes and fields. Joins are implicit by the relationships between the objects, there is no need to specify that stuff.Depending on the classes/fields, start with something likeSELECT this.id, this.name, catalog.id, catalog.name, catalog.line.id, catalog.line.name FROM ProductsWHERE ...Also JDOQL is infinitely extensible (in DataNucleus) since the user can define the functions/methods etc.
DataNucleus
waaa- realization: a join = filter => break into stages... Got to test against big(O) thoughSQL is inherent to RDBMS, but also in our DNAs i guess. Thanks.
k.honsali