I work on a large and old application consisting of a server and a fat client. Part of what the application does is handle a large-ish (a few 100MBs) database of frequently changing data (~a dozen rows per second). Because of the size, there is a master copy of the database on the server and a local copy on every client and they need to be synced. Changes can either be caused by outside events coming to the server or they can come from user interactions. In the first case, the server updates the master DB and propagates that to the clients. In the second case, the client sends a request-to-change to the server, the server updates the DB and propagates that to all clients, including the original one. In addition, clients have a "undo"-feature that allows to reverse-apply the couple of last changes the user caused.
We use JPA/Hibernate as an ORM layer between the database and our code, both on the client and the server side. But there are different database backends on both sides.
At the moment, our solution is old, half-baked legacy code: Diffs between objects are calculated based on string representations of their attributes. The corresponding old/new pairs of string-values get distributed for syncing and stored in a separate table for later undos. Lots of things can and sometimes do go wrong the way it is now.
What is the preferred way of doing this? I've looked through some Hibernate docs and tutorials, but it seems there is no ready made solution with JPA that does this out of the box. I could probably design something that's less half-baked, maybe three-quarters-baked with @Audit and Entity Listeners. But I'm assuming that some smart people have already come up with some design pattern that realises this. Can someone please point me in the right direction?