I have an app build with JSF2.x Spring IoC,transactions and JPA over Hibernate. This is a fully functional call center app.
The challenge is that now I want to add some HR functionality where the HR team would perform various tasks. My initial thought was to create this as an module in order to be able to deploy/undeploy independently from the mother app. The communication between main app and HR module will be implemented via REST/SOAP WS or any other async communication technology (JMS).
With this in my mind I already see one problem: database replication. Because the HR module will work with user or user profile objects from my main app. So in this scenario I would send this objects to HR module and probably there I would have a local database where this info will be duplicated and hard to maintain in sync.
The other approach would be to have 2 apps that share the same database, and I guess that this will eliminate the need for a communication layer (WS/JMS…), because the both apps read/write to same database. but as it was expected this also have some drawbacks:
- performing operations from HR module to a user entity will break the cache layer that it is used by the main app;
- sharing the same database will arise some scenarios where for some HR functionality to be forced to alter DB schema, and the to redeploy the main app.
How should I proceed in order to obtain a high level of independence between main app and various modules and without replicate some data for each module?
1
Determine a master responsible for each piece of data
It seems very odd that both applications would need to change the same data. Instead, can you divide the data between the two applications so only one of the applications has the responsibility to change a specific piece of data? For example, the call center application itself could handle changes to the contact information for a client (telephone, e-mail) as they are dealing with it directly. The HR application could be responsible for all changes to the financial data for the client (what percentage they get off the total for ordering).
Avoid reading each other’s database
Two applications reading on a single database makes for a big headache. Updates to the application become more difficult because they impact both applications, testing involves both applications and you have to keep development in sync to avoid breaking changes. Instead, opt to have the database belong to a single application that exposes a contract to access or expose and – if need be – change the data. If you can clearly determine who is responsible for what pieces of data you can even have the master send its data over to the slave. The HR application could receive data from the call center application and keep it read-only in its own database, stored in a table structure that makes sense to the HR application.
Determine how stale your data can be
Do both applications need access to the data real-time? Let’s assume the HR app updates a typo in the name of the company the client works for, how bad would it be to have this information only show up the next day? This will determine your data acess strategy. If it needs to be real-time, use a webservice for data access or send messages between your applications to alter the data real-time. If the data can be more stale you can use a scheduled task to sync the data, for example once a night. The more you couple your applications (through webservices or shared databases), the more dependant they become. If your HR and call center app use webservices, having one of the applications go down (for updates or due to a crash) effectively brings both down. Synchronising data that is stored in their own databases avoids having this kind of interdependency. If you NEED that kind of reliability is another question.
2