Persistence Using Layers
Managing the persistent storage for an application is another tremendous source of code that can bog down application development. Depending on what you need, some light-weight way to embed SQL in your code, or some object/relational mapping technique, or your NoSQL or JSON oriented database using the API of choice are your best options. You can use all of these approaches with StrataCode today.
StrataCode has JPA layers for generating a default persistence.xml file from annotations. Another nice practice is to break your domain models up into layers based on logical groupings of properties, maybe considering what groups might be stored separately. For example, in a User object you might separate out login properties, profile properties, and orderHistory as three separate groups. This would make it easier to code-generate more flexible domain models in the future.
There are several planned features to leverage layers with persistence:
Persistence with synchronization: the sync system can automatically persist objects on the server using a database or client using an offline store. Errors and conflicts can be reflected back for the application to resolve using error handlers and conflict resolution policies.
Use layers to provide a unified application programming model for data which is stored in different persistent stores - SQL, NoSQL, JSON in SQL. Code generation will generate a combined object which lazily pulls in from each data source, exposing the unified contract, doing joins as necessary directed by annotations or some code hooks. Since you specify the meta-data per layer, with some more framework level support, we will be able to use this organization to build one configuration which groups all fields in the same database, and another which groups them in separate databases. This new framework support could detect the id properties in the overlapping model and generate the code necessary to seamlessly implement a split database organization with "on demand" join.
Use layers to store changes to a record or set of records. A layer will store a set of changes made to an external data store, and present a view of the complete data store with the changes merged, while keeping modifications made in this separate layer. This is a powerful pattern that could be used to stage data changes to your content database. You can turn that layer on or off quickly to either see the changes or not. Run your tests so they are making changes in a temporary layer but in an environment where they can point to the production database for accuracy.
Use code-generation to make "plain java objects" work in a transactional way. They will use a shared cache for read-only operations. On the first change in a transaction for a given instance, we'll create a separate property store for the changes for that transaction. If we can't synchronize access to the instance, we can use a thread-local lookup in the getX method to find the store for that thread. Either way, the getX method will consult this store before using the global cache so only the transaction will see the change until it's committed. We'll support various ways of synchronizing the global cache with a backend store. This architecture will perform much faster than using hibernate or any other JPA implementation in a cached environment with a large graph of objects. It also maps nicely onto the scope system, so we'll have an efficient option to use these objects in scopes to serve as a cache of shared data.