skarfiol
skarfiol

Reputation: 131

JPA client-server replication/synchronization framework?

I have a simple client(JavaSE, Swing) - server(Java EE, EJB, JPA) architecture.

I would like to create a client side "cache" for my server side entities. For example, if I download an entity, I will store it in an Embedded Derby DB (with client side JPA), so the next time, when its needed, the client can look up first in its own DB and retrieve the entity from there to spare network communication. (Simple replication)

My problem starts with the IDs of the entities: having the same ID on both client and server side sounds a real bad practice, so I should store some mapping for the client side ID and the server side ID of an entity. The problem continues, because I have so many entites (15~20..), and associations amongst them.

Placing the right ID-s towards server communication (updating, merging) or towards client side promotes to have some recursive and maybe reflective code, an engine, which keeps tracking of the mapped ID-s:

Does anyone know about such a framework, especially for JPA users? Or do you have some implementation tips maybe? // I would like to solve this issue at the application-persistence level, if possible

Thanks in advance, András Liter

Upvotes: 1

Views: 1203

Answers (2)

Allan
Allan

Reputation: 2939

I recently coded a client that has to sync entities with the server, storing them in a local Derby DB. The client can also create new entities which have to be synced with the server. In addition both client and server used the same Entity classes, DAO and Service layer components. I'll share the problem I ran into and my solutions. If they are relevant I hope they help.

I used the same ID fields on client and server.

One problem you MIGHT have is with auto generated keys. My server keys were auto generated in a MS SQL Server database. My entities were annotated as such.

@Id
@GeneratedValue(strategy = GenerationType.AUTO)

The first time I synced the entities to my local Derby database I needed a way to use the same ID that the server has.

To do this, I created an orm.xml file on the client application that allows direct input of the key. orm.xml will override the annotations.

See: Sequence Generator in persistence.xml

Of course in the above link, I specified a custom generator for the local database. You would specify the ID field as having no auto generation.

I needed a generator on the client because I was creating new entities. In this case I needed a way to generate new keys AND insert entities from the server. I used Hibernate as my JPA provider. This allowed me to create a listener that figured out if the entity was new or if already had an id. Based on that I either allowed the generator to create the id or I used the ID that the entity already had.

See: JPA ID Generation Strategy

Next I needed a way for the server to know what entities are new. From the link above you can see that my generator started at 100000000. In my case this number is high enough to because the server will not have an ID that high for a long time (if ever). Of course it's not the cleanest solution and I tried using a negative number for all IDs on the client but Hibernate wouldn't create the sequence properly due to a bug.

See: JPA / Hibernate / Derby TableGenerator use negative values

So on the server I check all the entities coming up, if any of them are above the magic number (100000000), I null out their ID before the save. This way the server will add them as new and they will get an ID from the server. Then they have to be synced back to the client etc.

Hope this helped.

Upvotes: 0

James
James

Reputation: 18379

What not use the same ids? Seems like you would not have any problems if you didn't try to have different ones...

Upvotes: 1

Related Questions